Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A0-1259: Add metadata to PSP22 contracts #585

Merged
merged 3 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions contracts/game_token/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ pub mod game_token {
codegen::{EmitEvent, Env},
reflect::ContractEventBase,
};
use ink_prelude::format;
use ink_prelude::{format, string::String};
use ink_storage::traits::SpreadAllocate;
use openbrush::{contracts::psp22::*, traits::Storage};
use openbrush::{
contracts::psp22::{extensions::metadata::*, Internal},
traits::Storage,
};

pub const BALANCE_OF_SELECTOR: [u8; 4] = [0x65, 0x68, 0x38, 0x2f];
pub const TRANSFER_SELECTOR: [u8; 4] = [0xdb, 0x20, 0xf9, 0xf5];
Expand All @@ -23,12 +26,16 @@ pub mod game_token {
pub struct GameToken {
#[storage_field]
psp22: psp22::Data,
#[storage_field]
metadata: metadata::Data,
/// access control contract
access_control: AccountId,
}

impl PSP22 for GameToken {}

impl PSP22Metadata for GameToken {}

// emit events
// https://github.com/w3f/PSPs/blob/master/PSPs/psp-22.md
impl Internal for GameToken {
Expand Down Expand Up @@ -93,11 +100,14 @@ pub mod game_token {
}

impl GameToken {
/// Creates a new contract with the specified initial supply.
/// Creates a new game token with the specified initial supply.
///
/// The token will have its name and symbol set in metadata to the specified values.
/// Decimals are fixed at 18.
///
/// Will revert if called from an account without a proper role
/// Will revert if called from an account without a proper role
#[ink(constructor)]
pub fn new(total_supply: Balance) -> Self {
pub fn new(name: String, symbol: String, total_supply: Balance) -> Self {
let caller = Self::env().caller();
let code_hash = Self::env()
.own_code_hash()
Expand All @@ -116,6 +126,9 @@ pub mod game_token {

match role_check {
Ok(_) => ink_lang::codegen::initialize_contract(|instance: &mut GameToken| {
instance.metadata.name = Some(name);
instance.metadata.symbol = Some(symbol);
instance.metadata.decimals = 18;
instance
._mint(instance.env().caller(), total_supply)
.expect("Should mint");
Expand Down
91 changes: 48 additions & 43 deletions contracts/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,29 @@ function instrument_game_token {

local __resultvar=$1
local contract_name=$2
local salt=$3
local token_name=\"$3\"
obrok marked this conversation as resolved.
Show resolved Hide resolved
local token_symbol=\"$4\"
local salt=$5

# --- CREATE AN INSTANCE OF THE TOKEN CONTRACT

cd "$CONTRACTS_PATH"/$contract_name
cd "$CONTRACTS_PATH"/"$contract_name"

local contract_address=$(cargo contract instantiate --url $NODE --constructor new --args $TOTAL_BALANCE --suri "$AUTHORITY_SEED" --salt $salt)
local contract_address=$(echo "$contract_address" | grep Contract | tail -1 | cut -c 15-)
local contract_address
contract_address=$(cargo contract instantiate --url "$NODE" --constructor new --args "$token_name" "$token_symbol" "$TOTAL_BALANCE" --suri "$AUTHORITY_SEED" --salt "$salt")
contract_address=$(echo "$contract_address" | grep Contract | tail -1 | cut -c 15-)

echo $contract_name "token contract instance address: " $contract_address
echo "$contract_name token contract instance address: $contract_address"

# --- GRANT PRIVILEDGES ON THE TOKEN CONTRACT

cd "$CONTRACTS_PATH"/access_control

# set the admin and the owner of the contract instance
cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Admin('$contract_address')' --suri "$AUTHORITY_SEED"
cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Owner('$contract_address')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Admin('"$contract_address"')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Owner('"$contract_address"')' --suri "$AUTHORITY_SEED"

eval $__resultvar="'$contract_address'"
eval "$__resultvar='$contract_address'"
}

function deploy_and_instrument_game {
Expand All @@ -38,57 +41,59 @@ function deploy_and_instrument_game {

# --- UPLOAD CONTRACT CODE

cd "$CONTRACTS_PATH"/$contract_name
link_bytecode $contract_name 4465614444656144446561444465614444656144446561444465614444656144 $ACCESS_CONTROL_PUBKEY
rm target/ink/$contract_name.wasm
node ../scripts/hex-to-wasm.js target/ink/$contract_name.contract target/ink/$contract_name.wasm
cd "$CONTRACTS_PATH/$contract_name"
link_bytecode "$contract_name" 4465614444656144446561444465614444656144446561444465614444656144 "$ACCESS_CONTROL_PUBKEY"
rm target/ink/"$contract_name".wasm
node ../scripts/hex-to-wasm.js target/ink/"$contract_name".contract target/ink/"$contract_name".wasm

local code_hash=$(cargo contract upload --url $NODE --suri "$AUTHORITY_SEED")
local code_hash=$(echo "$code_hash" | grep hash | tail -1 | cut -c 15-)
local code_hash
code_hash=$(cargo contract upload --url "$NODE" --suri "$AUTHORITY_SEED")
code_hash=$(echo "$code_hash" | grep hash | tail -1 | cut -c 15-)

# --- GRANT INIT PRIVILEDGES ON THE CONTRACT CODE
# --- GRANT INIT PRIVILEGES ON THE CONTRACT CODE

cd "$CONTRACTS_PATH"/access_control

cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Initializer('$code_hash')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Initializer('"$code_hash"')' --suri "$AUTHORITY_SEED"

# --- CREATE AN INSTANCE OF THE CONTRACT

cd "$CONTRACTS_PATH"/$contract_name
cd "$CONTRACTS_PATH/$contract_name"

local contract_address=$(cargo contract instantiate --url $NODE --constructor new --args $game_token $LIFETIME --suri "$AUTHORITY_SEED")
local contract_address=$(echo "$contract_address" | grep Contract | tail -1 | cut -c 15-)
local contract_address
contract_address=$(cargo contract instantiate --url "$NODE" --constructor new --args "$game_token" "$LIFETIME" --suri "$AUTHORITY_SEED")
contract_address=$(echo "$contract_address" | grep Contract | tail -1 | cut -c 15-)

echo $contract_name "contract instance address: " $contract_address
echo "$contract_name contract instance address: $contract_address"

# --- GRANT PRIVILEDGES ON THE CONTRACT

cd "$CONTRACTS_PATH"/access_control

cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Owner('$contract_address')' --suri "$AUTHORITY_SEED"
cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Admin('$contract_address')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Owner('"$contract_address"')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Admin('"$contract_address"')' --suri "$AUTHORITY_SEED"

# --- TRANSFER TOKENS TO THE CONTRACT

cd "$CONTRACTS_PATH"/game_token

cargo contract call --url $NODE --contract $game_token --message PSP22::transfer --args $contract_address $GAME_BALANCE "[0]" --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$game_token" --message PSP22::transfer --args "$contract_address" "$GAME_BALANCE" "[0]" --suri "$AUTHORITY_SEED"

# --- WHITELIST ACCOUNTS FOR PLAYING

cd "$CONTRACTS_PATH"/$contract_name
cd "$CONTRACTS_PATH/$contract_name"

cargo contract call --url $NODE --contract $contract_address --message IButtonGame::bulk_allow --args $WHITELIST --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$contract_address" --message IButtonGame::bulk_allow --args "$WHITELIST" --suri "$AUTHORITY_SEED"

eval $__resultvar="'$contract_address'"
eval "$__resultvar='$contract_address'"
}

function link_bytecode() {
local contract=$1
local placeholder=$2
local replacement=$3

sed -i 's/'$placeholder'/'$replacement'/' target/ink/$contract.contract
sed -i 's/'"$placeholder"'/'"$replacement"'/' "target/ink/$contract.contract"
}

# --- GLOBAL CONSTANTS
Expand Down Expand Up @@ -119,70 +124,70 @@ cargo contract build --release

cd "$CONTRACTS_PATH"/access_control

CONTRACT=$(cargo contract instantiate --url $NODE --constructor new --suri "$AUTHORITY_SEED")
CONTRACT=$(cargo contract instantiate --url "$NODE" --constructor new --suri "$AUTHORITY_SEED")
ACCESS_CONTROL=$(echo "$CONTRACT" | grep Contract | tail -1 | cut -c 15-)
ACCESS_CONTROL_PUBKEY=$(docker run --rm --entrypoint "/bin/sh" "${NODE_IMAGE}" -c "aleph-node key inspect $ACCESS_CONTROL" | grep hex | cut -c 23- | cut -c 3-)

echo "access control contract address: " $ACCESS_CONTROL
echo "access control contract public key (hex): " $ACCESS_CONTROL_PUBKEY
echo "access control contract address: $ACCESS_CONTROL"
echo "access control contract public key \(hex\): $ACCESS_CONTROL_PUBKEY"

# --- UPLOAD TOKEN CONTRACT CODE

cd "$CONTRACTS_PATH"/game_token
# replace address placeholder with the on-chain address of the AccessControl contract
link_bytecode game_token 4465614444656144446561444465614444656144446561444465614444656144 $ACCESS_CONTROL_PUBKEY
link_bytecode game_token 4465614444656144446561444465614444656144446561444465614444656144 "$ACCESS_CONTROL_PUBKEY"
# remove just in case
rm target/ink/game_token.wasm
# NOTE : here we go from hex to binary using a nodejs cli tool
# availiable from https://github.com/fbielejec/polkadot-cljs
node ../scripts/hex-to-wasm.js target/ink/game_token.contract target/ink/game_token.wasm

CODE_HASH=$(cargo contract upload --url $NODE --suri "$AUTHORITY_SEED")
CODE_HASH=$(cargo contract upload --url "$NODE" --suri "$AUTHORITY_SEED")
GAME_TOKEN_CODE_HASH=$(echo "$CODE_HASH" | grep hash | tail -1 | cut -c 15-)

echo "button token code hash" $GAME_TOKEN_CODE_HASH
echo "button token code hash" "$GAME_TOKEN_CODE_HASH"

# --- GRANT INIT PRIVILEDGES ON THE TOKEN CONTRACT CODE

cd "$CONTRACTS_PATH"/access_control

# set the initializer of the token contract
cargo contract call --url $NODE --contract $ACCESS_CONTROL --message grant_role --args $AUTHORITY 'Initializer('$GAME_TOKEN_CODE_HASH')' --suri "$AUTHORITY_SEED"
cargo contract call --url "$NODE" --contract "$ACCESS_CONTROL" --message grant_role --args "$AUTHORITY" 'Initializer('"$GAME_TOKEN_CODE_HASH"')' --suri "$AUTHORITY_SEED"

#
# --- EARLY_BIRD_SPECIAL GAME
#

# --- CREATE AN INSTANCE OF THE TOKEN CONTRACT FOR THE EARLY_BIRD_SPECIAL GAME

start=`date +%s.%N`
start=$( date +%s.%N )

instrument_game_token EARLY_BIRD_SPECIAL_TOKEN game_token 0x4561726C79426972645370656369616C
instrument_game_token EARLY_BIRD_SPECIAL_TOKEN game_token Ubik UBI 0x4561726C79426972645370656369616C

# --- UPLOAD CODE AND CREATE AN INSTANCE OF THE EARLY_BIRD_SPECIAL GAME CONTRACT

deploy_and_instrument_game EARLY_BIRD_SPECIAL early_bird_special $EARLY_BIRD_SPECIAL_TOKEN
deploy_and_instrument_game EARLY_BIRD_SPECIAL early_bird_special "$EARLY_BIRD_SPECIAL_TOKEN"

#
# --- BACK_TO_THE_FUTURE GAME
#

# --- CREATE AN INSTANCE OF THE TOKEN CONTRACT FOR THE BACK_TO_THE_FUTURE GAME

instrument_game_token BACK_TO_THE_FUTURE_TOKEN game_token 0x4261636B546F546865467574757265
instrument_game_token BACK_TO_THE_FUTURE_TOKEN game_token Cyberiad CYB 0x4261636B546F546865467574757265

# --- UPLOAD CODE AND CREATE AN INSTANCE OF THE EARLY_BIRD_SPECIAL GAME CONTRACT

deploy_and_instrument_game BACK_TO_THE_FUTURE back_to_the_future $BACK_TO_THE_FUTURE_TOKEN
deploy_and_instrument_game BACK_TO_THE_FUTURE back_to_the_future "$BACK_TO_THE_FUTURE_TOKEN"

# spit adresses to a JSON file
cd "$CONTRACTS_PATH"

jq -n --arg early_bird_special $EARLY_BIRD_SPECIAL \
--arg back_to_the_future $BACK_TO_THE_FUTURE \
jq -n --arg early_bird_special "$EARLY_BIRD_SPECIAL" \
--arg back_to_the_future "$BACK_TO_THE_FUTURE" \
'{early_bird_special: $early_bird_special, back_to_the_future: $back_to_the_future}' > addresses.json

end=`date +%s.%N`
echo "Time elapsed:" $( echo "$end - $start" | bc -l )
end=$( date +%s.%N )
echo "Time elapsed: $( echo "$end - $start" | bc -l )"

exit $?