Skip to content

Commit

Permalink
A0-1259: Add metadata to PSP22 contracts (#585)
Browse files Browse the repository at this point in the history
* Add metadata to PSP22 contracts

* Fix shellcheck warnings in deploy.sh

* Remove const
  • Loading branch information
obrok authored Aug 15, 2022
1 parent 8b5b1b3 commit 8586152
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 48 deletions.
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\"
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 $?

0 comments on commit 8586152

Please sign in to comment.