├── .gitignore ├── scripts ├── deploy_proxy.sh ├── deploy_ssnlist.sh ├── pause.sh ├── unpause.sh ├── get_state.sh ├── deposit_funds.sh ├── stake_deposit.sh ├── drain_contract_balance.sh ├── withdraw_stake_rewards.sh ├── update_minstake.sh ├── update_maxstake.sh ├── withdraw_stake_amount.sh ├── remove_ssn.sh ├── update_admin.sh ├── update_contractmaxstake.sh ├── upgradeTo.sh ├── update_verifier.sh ├── changeProxyAdmin.sh ├── ssnlist.json ├── proxy.json ├── assign_stake_reward.sh ├── add_ssn.sh └── README.md ├── phase0 ├── tests │ ├── middle_contract.json │ ├── go.mod │ ├── middle_contract.scilla │ ├── transitions │ │ ├── proxy.go │ │ ├── exec.go │ │ ├── drain_contract_balance.go │ │ ├── update_min_stake.go │ │ ├── update_max_stake.go │ │ ├── deposit_funds.go │ │ ├── update_contract_max_stake.go │ │ ├── update_verifier.go │ │ ├── update_admin.go │ │ ├── update_staking_parameter.go │ │ ├── pause_and_unpause.go │ │ ├── change_proxy_admin.go │ │ ├── deploy_and_upgrade.go │ │ ├── assign_stake_reward.go │ │ ├── add_ssn.go │ │ └── remove_ssn.go │ ├── main │ │ └── main.go │ ├── README.md │ └── go.sum ├── Staked_Seed_Node_SSN_Operations-Report.pdf ├── scripts │ ├── Golang-ZLI │ │ ├── get_state.sh │ │ ├── Contract-Admin │ │ │ ├── unpause.sh │ │ │ ├── pause.sh │ │ │ ├── drain_contract_balance.sh │ │ │ ├── update_admin.sh │ │ │ ├── multisig_submit_pause_transaction.sh │ │ │ ├── multisig_submit_unpause_transaction.sh │ │ │ ├── update_verifier.sh │ │ │ ├── multisig_submit_drainContractBalance_transaction.sh │ │ │ ├── remove_ssn.sh │ │ │ ├── update_maxstake.sh │ │ │ ├── update_minstake.sh │ │ │ ├── multisig_submit_removeSsn_transaction.sh │ │ │ ├── multisig_submit_updateAdmin_transaction.sh │ │ │ ├── multisig_submit_updateVerifier_transaction.sh │ │ │ ├── update_contractmaxstake.sh │ │ │ ├── multisig_submit_updateMaxStake_transaction.sh │ │ │ ├── multisig_submit_updateMinStake_transaction.sh │ │ │ ├── multisig_submit_updateContractMaxStake_transaction.sh │ │ │ ├── multisig_submit_addSsn_transaction.sh │ │ │ └── add_ssn.sh │ │ ├── deploy_multisig_wallet.sh │ │ ├── deploy_proxy.sh │ │ ├── deploy_ssnlist.sh │ │ ├── SSN-Operators │ │ │ ├── withdraw_stake_rewards.sh │ │ │ ├── withdraw_stake_amount.sh │ │ │ └── stake_deposit.sh │ │ ├── multisig_sign_transaction.sh │ │ ├── multisig_execute_transaction.sh │ │ ├── Proxy-Admin │ │ │ ├── changeProxyAdmin.sh │ │ │ ├── upgradeTo.sh │ │ │ ├── multisig_submit_changeProxyAdmin_transaction.sh │ │ │ └── multisig_submit_upgradeTo_transaction.sh │ │ ├── deposit_funds.sh │ │ ├── ssnlist.json │ │ ├── proxy.json │ │ ├── wallet.json │ │ ├── verifier │ │ │ └── assign_stake_reward.sh │ │ ├── config.sh │ │ └── README.md │ ├── Java │ │ ├── src │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── zilliqa │ │ │ │ │ └── staking │ │ │ │ │ ├── EventParam.java │ │ │ │ │ └── EventLogEntry.java │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── zilliqa │ │ │ │ └── staking │ │ │ │ └── SSNOperatorTest.java │ │ ├── build.gradle │ │ └── README.md │ ├── README.md │ └── NodeJS │ │ ├── package.json │ │ ├── README.md │ │ ├── Contract-Admin │ │ ├── pause.js │ │ ├── unpause.js │ │ ├── drain_contract_balance.js │ │ ├── remove_ssn.js │ │ ├── update_admin.js │ │ ├── update_verifier.js │ │ ├── add_ssn.js │ │ └── update_staking_parameter.js │ │ ├── SSN-Operators │ │ ├── get_stake_rewards.js │ │ ├── get_stake_amount.js │ │ ├── withdraw_stake_rewards.js │ │ ├── get_stake_buffered_amount.js │ │ ├── stake_deposit.js │ │ └── withdraw_stake_amount.js │ │ ├── add_funds.js │ │ ├── Proxy-Admin │ │ ├── upgradeTo.js │ │ ├── changeProxyAdmin.js │ │ └── deploy.js │ │ └── verifier │ │ └── assign_stake_reward.js └── contracts │ └── proxy.scilla ├── tests ├── generateCompressedSSNlist.sh ├── go.mod ├── README.md ├── transitions │ ├── add_funds.go │ ├── unpause.go │ ├── pause.go │ ├── update_received_addr.go │ ├── update_staking_parameters.go │ ├── update_verifier.go │ ├── deploy_and_upgrade.go │ ├── drain_contract_balance.go │ ├── withdraw_stake_rewards_simulation.go │ ├── withdraw_stake_amount3.go │ ├── upgrade_to.go │ ├── assign_stake_reward.go │ ├── withdraw_comm.go │ ├── withdraw_stake_rewards2.go │ ├── update_admin.go │ ├── change_proxy_admin.go │ ├── withdraw_stake_rewards3.go │ ├── withdraw_stake_rewards.go │ ├── add_ssn.go │ ├── withdraw_stake_amount2.go │ ├── testing.go │ ├── assign_stake_reward2.go │ ├── add_ssn_after_upgrade.go │ ├── update_commission.go │ ├── delegate_stake.go │ ├── add_delegator.go │ └── withdraw_stake_amount.go ├── main │ └── main.go ├── generatedAccounts.json ├── deploy │ └── ssnlist.go └── go.sum └── .github └── workflows └── workflow.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /scripts/deploy_proxy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract deploy -c ../contracts/proxy.scilla -i proxy.json -------------------------------------------------------------------------------- /scripts/deploy_ssnlist.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract deploy -c ../contracts/ssnlist.scilla -i ssnlist.json -------------------------------------------------------------------------------- /scripts/pause.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t pause -r "[]" -f true 3 | -------------------------------------------------------------------------------- /scripts/unpause.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t unpause -r "[]" -f true 3 | -------------------------------------------------------------------------------- /phase0/tests/middle_contract.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "vname": "_scilla_version", 4 | "type": "Uint32", 5 | "value": "0" 6 | } 7 | ] -------------------------------------------------------------------------------- /tests/generateCompressedSSNlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rm ssnlist.scilla 3 | zli contract compact -i ../contracts/ssnlist.scilla -o ssnlist.scilla -------------------------------------------------------------------------------- /scripts/get_state.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract state -a bf72a8c7ae324aebf77202e5d8d7d17d4e9a90fc -u http://staking7-l2api.dev.z7a.xyz -------------------------------------------------------------------------------- /phase0/tests/go.mod: -------------------------------------------------------------------------------- 1 | module Zilliqa/stake-test 2 | 3 | go 1.13 4 | 5 | require github.com/Zilliqa/gozilliqa-sdk v0.0.0-20200201085548-db590549f1ff 6 | -------------------------------------------------------------------------------- /phase0/Staked_Seed_Node_SSN_Operations-Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zilliqa/staking-contract/HEAD/phase0/Staked_Seed_Node_SSN_Operations-Report.pdf -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/get_state.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source config.sh 3 | 4 | zli contract state -a ${STAKING_ADDRESS_SSNLIST} -u ${TESTNET_API_URL} -------------------------------------------------------------------------------- /scripts/deposit_funds.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t deposit_funds -r "[]" -m 100000000000000 -f true -------------------------------------------------------------------------------- /scripts/stake_deposit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t stake_deposit -r "[]" -m 10000000000000 -f true -------------------------------------------------------------------------------- /scripts/drain_contract_balance.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t drain_contract_balance -r "[]" -f true 3 | -------------------------------------------------------------------------------- /scripts/withdraw_stake_rewards.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t withdraw_stake_rewards -r "[]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/unpause.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${STAKING_ADDRESS_PROXY} -s ${KEY_STORE_PATH} -t unpause -r "[]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/deploy_multisig_wallet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract deploy -c ../../contracts/multisig_wallet.scilla -i wallet.json -s ${KEY_STORE_PATH} -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/deploy_proxy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source config.sh 3 | 4 | zli contract deploy -c ../../contracts/proxy.scilla -i proxy.json -s ${KEY_STORE_PATH} -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/pause.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -s ${KEY_STORE_PATH} -t pause -r "[]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/deploy_ssnlist.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source config.sh 3 | 4 | zli contract deploy -c ../../contracts/ssnlist.scilla -i ssnlist.json -k ${STAKING_PRIVKEY_ADMIN} -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/SSN-Operators/withdraw_stake_rewards.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t withdraw_stake_rewards -r "[]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/drain_contract_balance.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t drain_contract_balance -r "[]" -s ${KEY_STORE_PATH} -f true 3 | -------------------------------------------------------------------------------- /tests/go.mod: -------------------------------------------------------------------------------- 1 | module Zilliqa/stake-test 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210319034641-0161a0c9e0fe 7 | github.com/satori/go.uuid v1.2.0 // indirect 8 | ) 9 | -------------------------------------------------------------------------------- /scripts/update_minstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t update_minstake -r "[{\"vname\":\"min_stake\",\"type\":\"Uint128\",\"value\":\"10000000000\"}]" -f true 3 | -------------------------------------------------------------------------------- /scripts/update_maxstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t update_maxstake -r "[{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"1000000000000000\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Java/src/main/java/com/zilliqa/staking/EventParam.java: -------------------------------------------------------------------------------- 1 | package com.zilliqa.staking; 2 | 3 | public class EventParam { 4 | public String vname; 5 | public String type; 6 | public String value; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/withdraw_stake_amount.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t withdraw_stake_amount -r "[{\"vname\":\"amount\",\"type\":\"Uint128\",\"value\":\"500000000000\"}]" -f true 3 | -------------------------------------------------------------------------------- /scripts/remove_ssn.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t remove_ssn -r "[{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"}]" -f true 3 | -------------------------------------------------------------------------------- /scripts/update_admin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t update_admin -r "[{\"vname\":\"admin\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"}]" -f true 3 | -------------------------------------------------------------------------------- /scripts/update_contractmaxstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t update_contractmaxstake -r "[{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"10000000000000000\"}]" -f true 3 | -------------------------------------------------------------------------------- /scripts/upgradeTo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 0x09710e00256db2e3db4b44f597f17f3d97f06318 -t upgradeTo -r "[{\"vname\":\"newImplementation\",\"type\":\"ByStr20\",\"value\":\"0x1256e7c364d4f5b4b579541d1483f4be9ab5bc3d\"}]" -f true -------------------------------------------------------------------------------- /scripts/update_verifier.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t update_verifier -r "[{\"vname\":\"verif\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Java/src/main/java/com/zilliqa/staking/EventLogEntry.java: -------------------------------------------------------------------------------- 1 | package com.zilliqa.staking; 2 | 3 | 4 | public class EventLogEntry { 5 | public String address; 6 | public String _eventname; 7 | public EventParam[] params; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/changeProxyAdmin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t changeProxyAdmin -r "[{\"vname\":\"newAdmin\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/multisig_sign_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SignTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"transactionId\",\"type\":\"Uint32\",\"value\":\"${TRANSACTION_ID}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/SSN-Operators/withdraw_stake_amount.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t withdraw_stake_amount -r "[{\"vname\":\"amount\",\"type\":\"Uint128\",\"value\":\"500000000000\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/multisig_execute_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t ExecuteTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"transactionId\",\"type\":\"Uint32\",\"value\":\"${TRANSACTION_ID}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/update_admin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${STAKING_ADDRESS_PROXY} -s ${KEY_STORE_PATH} -t update_admin -r "[{\"vname\":\"admin\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Proxy-Admin/changeProxyAdmin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t changeProxyAdmin -r "[{\"vname\":\"newAdmin\",\"type\":\"ByStr20\",\"value\":\"0x${STAKING_PRIVKEY_ADMIN}\"}]" -f true 5 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/deposit_funds.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source config.sh 3 | 4 | # Update the values below 5 | FUNDS_IN_QA="100000000000000" 6 | 7 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t deposit_funds -k ${STAKING_PRIVKEY_ADMIN} -r "[]" -m ${FUNDS_IN_QA} -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Proxy-Admin/upgradeTo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t upgradeTo -s ${KEY_STORE_PATH} -r "[{\"vname\":\"newImplementation\",\"type\":\"ByStr20\",\"value\":\"0x${STAKING_ADDRESS_SSNLIST}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_pause_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomPauseTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_unpause_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUnpauseTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/update_verifier.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t update_verifier -k ${STAKING_PRIVKEY_ADMIN} -r "[{\"vname\":\"verif\",\"type\":\"ByStr20\",\"value\":\"0x${STAKING_ADDRESS_VERIF}\"}]" -f true 5 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_drainContractBalance_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomDrainContractBalanceTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Java/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | group 'com.zilliqa' 6 | version '0.0.1-SNAPSHOT' 7 | 8 | sourceCompatibility = 1.8 9 | 10 | repositories { 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile group: 'org.firestack', name: 'laksaj', version: '1.0.4-RELEASE' 16 | } 17 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/remove_ssn.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | SSN_ADDR="0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 6 | 7 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t remove_ssn -r "[{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"${SSN_ADDR}\"}]" -f true 8 | -------------------------------------------------------------------------------- /phase0/scripts/README.md: -------------------------------------------------------------------------------- 1 | # Seed Node Staking sample code and command 2 | Currently, we have sample code/command for the following: 3 | - [Golang Zilliqa command line utility](./Golang-ZLI) 4 | - [NodeJs](./NodeJS) 5 | - [Java](./Java) 6 | 7 | If you need support for other languages, we reach out to us via [Discord](https://discord.gg/XMRE9tt) 8 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/update_maxstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | FUNDS_IN_QA="10000000000000" 6 | 7 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t update_maxstake -k ${STAKING_PRIVKEY_ADMIN} -r "[{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"${FUNDS_IN_QA}\"}]" -f true 8 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/update_minstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | FUNDS_IN_QA="10000000000" 6 | 7 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t update_minstake -k ${STAKING_PRIVKEY_ADMIN} -r "[{\"vname\":\"min_stake\",\"type\":\"Uint128\",\"value\":\"${FUNDS_IN_QA}\"}]" -f true 8 | -------------------------------------------------------------------------------- /scripts/ssnlist.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "vname": "_scilla_version", 3 | "type": "Uint32", 4 | "value": "0" 5 | }, { 6 | "vname": "init_admin", 7 | "type": "ByStr20", 8 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 9 | }, { 10 | "vname": "proxy_address", 11 | "type": "ByStr20", 12 | "value": "0x09710e00256db2e3db4b44f597f17f3d97f06318" 13 | }] -------------------------------------------------------------------------------- /scripts/proxy.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "vname": "_scilla_version", 3 | "type": "Uint32", 4 | "value": "0" 5 | }, { 6 | "vname": "init_admin", 7 | "type": "ByStr20", 8 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 9 | }, { 10 | "vname": "init_implementation", 11 | "type": "ByStr20", 12 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 13 | }] -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_removeSsn_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomRemoveSsnTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"${SSN_ADDR}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_updateAdmin_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpdateAdminTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"admin\",\"type\":\"ByStr20\",\"value\":\"${ADMIN}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_updateVerifier_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpdateVerifierTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"verif\",\"type\":\"ByStr20\",\"value\":\"${VERIFIER}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/update_contractmaxstake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | FUNDS_IN_QA="1000000000000000" 6 | 7 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t update_contractmaxstake -k ${STAKING_PRIVKEY_ADMIN} -r "[{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"${FUNDS_IN_QA}\"}]" -f true 8 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/ssnlist.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "vname": "_scilla_version", 3 | "type": "Uint32", 4 | "value": "0" 5 | }, { 6 | "vname": "init_admin", 7 | "type": "ByStr20", 8 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 9 | }, { 10 | "vname": "proxy_address", 11 | "type": "ByStr20", 12 | "value": "0x09710e00256db2e3db4b44f597f17f3d97f06318" 13 | }] -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Proxy-Admin/multisig_submit_changeProxyAdmin_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomChangeProxyAdminTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"newAdmin\",\"type\":\"ByStr20\",\"value\":\"${NEW_ADMIN}\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Proxy-Admin/multisig_submit_upgradeTo_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpgradeToTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"newImplementation\",\"type\":\"ByStr20\",\"value\":\"${NEW_IMPL}\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/SSN-Operators/stake_deposit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | STAKING_PRIVKEY_SSN="38f3715e7ef9b5a5080171dca4cb37b05eaa7e3b0d9a9427a11e021e1029525d" 6 | FUNDS_IN_QA="100000000000000" 7 | 8 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t stake_deposit -k ${STAKING_PRIVKEY_SSN} -r "[]" -m ${FUNDS_IN_QA} -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/proxy.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "vname": "_scilla_version", 3 | "type": "Uint32", 4 | "value": "0" 5 | }, { 6 | "vname": "init_admin", 7 | "type": "ByStr20", 8 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 9 | }, { 10 | "vname": "init_implementation", 11 | "type": "ByStr20", 12 | "value": "0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 13 | }] -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_updateMaxStake_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpdateMaxStakeTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"${MAX_STAKE}\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_updateMinStake_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpdateMinStakeTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"min_stake\",\"type\":\"Uint128\",\"value\":\"${MIN_STAKE}\"}]" -f true 3 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | ### Requirements 2 | 3 | Golang (minimum version: go.1.12): 4 | * [Download page](https://golang.org/dl/) 5 | * [Installation instructions](https://golang.org/doc/install) 6 | 7 | Zilliqa command tool [zli](https://github.com/Zilliqa/zli) 8 | 9 | ### Run tests 10 | 11 | Run the following command to test(under tests directory): 12 | 13 | ```go 14 | go run main/main.go 15 | ``` -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_updateContractMaxStake_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomUpdateContractMaxStakeTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"max_stake\",\"type\":\"Uint128\",\"value\":\"${MAX_STAKE}\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tests", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@zilliqa-js/zilliqa": "^0.9.0", 13 | "bn.js": "^5.1.1", 14 | "tslib": "^1.11.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/assign_stake_reward.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t assign_stake_reward -r "[{\"vname\":\"ssnreward_list\",\"type\":\"List SsnRewardShare\",\"value\":[{\"constructor\":\"SsnRewardShare\",\"argtypes\":[],\"arguments\":[\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\",\"50000000\"]}]},{\"vname\":\"reward_blocknum\",\"type\":\"Uint32\",\"value\":\"50000\"}]" -f true -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/wallet.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "vname": "_scilla_version", 3 | "type": "Uint32", 4 | "value": "0" 5 | }, { 6 | "vname": "owners_list", 7 | "type": "List ByStr20", 8 | "value": ["0x8ea24f4debb10f1ef1b0448730abef62f188aee1","0x20ff646c47cbef9709ebdab505ebfa230a728499","0x5fa0e52b9cd475f31d22244d52b076601d031572"] 9 | }, { 10 | "vname": "required_signatures", 11 | "type": "Uint32", 12 | "value": "2" 13 | }] -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/verifier/assign_stake_reward.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t assign_stake_reward -r "[{\"vname\":\"ssnreward_list\",\"type\":\"List SsnRewardShare\",\"value\":[{\"constructor\":\"SsnRewardShare\",\"argtypes\":[],\"arguments\":[\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\",\"50000000\"]}]},{\"vname\":\"reward_blocknum\",\"type\":\"Uint32\",\"value\":\"50000\"}]" -f true -------------------------------------------------------------------------------- /tests/transitions/add_funds.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "errors" 4 | 5 | func (t *Testing) AddFunds() { 6 | t.LogStart("AddFunds") 7 | proxy, ssnlist := t.DeployAndUpgrade() 8 | ssnlist.LogContractStateJson() 9 | 10 | proxy.Unpause() 11 | proxy.AddFunds("10000") 12 | ssnlist.LogContractStateJson() 13 | 14 | if ssnlist.GetBalance() != "10000" { 15 | t.LogError("AddFunds",errors.New("balance error")) 16 | } 17 | 18 | t.LogEnd("AddFunds") 19 | } 20 | -------------------------------------------------------------------------------- /phase0/tests/middle_contract.scilla: -------------------------------------------------------------------------------- 1 | scilla_version 0 2 | 3 | library MiddleContract 4 | 5 | let zero = Uint128 0 6 | 7 | let one_msg = 8 | fun (m : Message) => 9 | let e = Nil {Message} in 10 | Cons {Message} m e 11 | 12 | contract MiddleContract() 13 | 14 | transition stake_deposit (proxy_address : ByStr20) 15 | accept; 16 | msg = {_tag : "stake_deposit"; _recipient : proxy_address; _amount : _amount}; 17 | msgs = one_msg msg; 18 | send msgs 19 | end 20 | 21 | transition AddFunds() 22 | accept 23 | end -------------------------------------------------------------------------------- /scripts/add_ssn.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a 09710e00256db2e3db4b44f597f17f3d97f06318 -t add_ssn -r "[{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"0xb2e51878722d8b6d2c0f97e995a7276d64c1618b\"},{\"vname\":\"stake_amount\",\"type\":\"Uint128\",\"value\":\"0\"},{\"vname\":\"rewards\",\"type\":\"Uint128\",\"value\":\"0\"},{\"vname\":\"urlraw\",\"type\":\"String\",\"value\":\"zilliqacom\"},{\"vname\":\"urlapi\",\"type\":\"String\",\"value\":\"apizilliqacom\"},{\"vname\":\"buffered_deposit\",\"type\":\"Uint128\",\"value\":\"0\"}]" -f true 3 | -------------------------------------------------------------------------------- /phase0/tests/transitions/proxy.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "github.com/Zilliqa/gozilliqa-sdk/provider" 4 | 5 | type Proxy struct { 6 | Addr string 7 | ImplAddress string 8 | Provider *provider.Provider 9 | } 10 | 11 | func NewProxy(url, proxy, impl string) *Proxy { 12 | p := provider.NewProvider(url) 13 | return &Proxy{ 14 | Addr: proxy, 15 | ImplAddress: impl, 16 | Provider: p, 17 | } 18 | } 19 | 20 | func (p *Proxy) extraEventName(events []interface{}) string { 21 | logs := events[0] 22 | log := logs.(map[string]interface{}) 23 | event := log["_eventname"].(string) 24 | return event 25 | } 26 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/multisig_submit_addSsn_transaction.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | zli contract call -a ${MULTISIG_WALLET_ADDRESS} -t SubmitCustomAddSsnTransaction -s ${KEY_STORE_PATH} -r "[{\"vname\":\"proxyContract\",\"type\":\"ByStr20\",\"value\":\"${PROXY_CONTRACT}\"},{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"${SSN_ADDR}\"},{\"vname\":\"stake_amount\",\"type\":\"Uint128\",\"value\":\"${STAKE_AMOUNT}\"},{\"vname\":\"rewards\",\"type\":\"Uint128\",\"value\":\"${REWARDS}\"},{\"vname\":\"urlraw\",\"type\":\"String\",\"value\":\"${URLRAW}\"},{\"vname\":\"urlapi\",\"type\":\"String\",\"value\":\"${URLAPI}\"},{\"vname\":\"buffered_deposit\",\"type\":\"Uint128\",\"value\":\"${BUFFERED_DEPOSIT}\"}]" -f true -------------------------------------------------------------------------------- /tests/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "Zilliqa/stake-test/transitions" 4 | 5 | func main() { 6 | t := transitions.NewTesting() 7 | t.UpgradeTo() 8 | t.ChangeProxyAdmin() 9 | t.Pause() 10 | t.Unpause() 11 | t.UpdateAdmin() 12 | t.UpdateVerifier() 13 | t.AddFunds() 14 | t.DrainContractBalance() 15 | t.UpdateStakingParameters() 16 | t.AddSSN() 17 | t.AddDelegator() 18 | t.DelegateStake() 19 | t.UpdateReceiveAddr() 20 | t.AssignStakeReward() 21 | t.AssignStakeReward2() 22 | t.WithDrawStakeAmount() 23 | t.WithDrawStakeAmount2() 24 | t.WithDrawStakeAmount3() 25 | t.AddSSNAfterUpgrade() 26 | t.UpdateComm() 27 | t.WithdrawComm() 28 | t.WithdrawStakeReward() 29 | t.WithdrawStakeReward2() 30 | t.WithdrawStakeReward3() 31 | } 32 | -------------------------------------------------------------------------------- /phase0/tests/transitions/exec.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "os/exec" 8 | ) 9 | 10 | func ExecZli(arg ...string) (error, string) { 11 | cmd := exec.Command("zli", arg...) 12 | stdout, err := cmd.StdoutPipe() 13 | if err != nil { 14 | return nil, err.Error() 15 | } 16 | defer stdout.Close() 17 | fmt.Println(cmd.String()) 18 | if err := cmd.Start(); err != nil { 19 | return errors.New(fmt.Sprintf("exec error on command: \"zli %s\" %s", arg[0], err.Error())), "" 20 | } 21 | opBytes, err := ioutil.ReadAll(stdout) 22 | if err != nil { 23 | return nil, err.Error() 24 | } 25 | if err := cmd.Wait(); err != nil { 26 | return errors.New(fmt.Sprintf("exec error on wait: \"zli %s\" %s", arg[0], err.Error())), "" 27 | } 28 | return nil, string(opBytes) 29 | } 30 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/Contract-Admin/add_ssn.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source ../config.sh 3 | 4 | # Update the values below 5 | SSN_ADDR="0xb2e51878722d8b6d2c0f97e995a7276d64c1618b" 6 | STAKE_AMOUNT="0" 7 | REWARDS="0" 8 | URLRAW="https://dev-api.zilliqa.com/" 9 | URLAPI="https://dev-api.zilliqa.com/" 10 | BUFFERED_DEPOSIT="0" 11 | 12 | zli contract call -a ${STAKING_ADDRESS_PROXY} -t add_ssn -k ${STAKING_PRIVKEY_ADMIN} -r "[{\"vname\":\"ssnaddr\",\"type\":\"ByStr20\",\"value\":\"${SSN_ADDR}\"},{\"vname\":\"stake_amount\",\"type\":\"Uint128\",\"value\":\"${STAKE_AMOUNT}\"},{\"vname\":\"rewards\",\"type\":\"Uint128\",\"value\":\"${REWARDS}\"},{\"vname\":\"urlraw\",\"type\":\"String\",\"value\":\"${URLRAW}\"},{\"vname\":\"urlapi\",\"type\":\"String\",\"value\":\"${URLAPI}\"},{\"vname\":\"buffered_deposit\",\"type\":\"Uint128\",\"value\":\"${BUFFERED_DEPOSIT}\"}]" -f true 13 | -------------------------------------------------------------------------------- /tests/transitions/unpause.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | func (t *Testing) Unpause() { 8 | t.LogStart("Unpause") 9 | 10 | proxy,ssnlist := t.DeployAndUpgrade() 11 | 12 | // as non admin, unpasue 13 | ssnlist.LogContractStateJson() 14 | proxy.UpdateWallet(key2) 15 | tnx,err := proxy.Unpause() 16 | t.AssertError(err) 17 | receipt := t.GetReceiptString(tnx) 18 | log.Println(receipt) 19 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))])") 20 | ssnlist.LogContractStateJson() 21 | 22 | // as admin, unpause 23 | proxy.UpdateWallet(key1) 24 | tnx,err2 := proxy.Unpause() 25 | if err2 != nil { 26 | t.LogError("Unpause",err2) 27 | } 28 | receipt = t.GetReceiptString(tnx) 29 | log.Println(receipt) 30 | ssnlist.LogContractStateJson() 31 | t.LogEnd("Unpause") 32 | } 33 | -------------------------------------------------------------------------------- /phase0/tests/transitions/drain_contract_balance.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "errors" 5 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 6 | "strconv" 7 | ) 8 | 9 | func (p *Proxy) drainContractBalance(pri string) error { 10 | proxy, _ := bech32.ToBech32Address(p.Addr) 11 | if err2, _ := ExecZli("contract", "call", 12 | "-k", pri, 13 | "-a", proxy, 14 | "-t", "drain_contract_balance", 15 | "-f", "true", 16 | "-r", "[]"); err2 != nil { 17 | return errors.New("call transition error: " + err2.Error()) 18 | } else { 19 | m := p.Provider.GetBalance(p.ImplAddress).Result.(map[string]interface{}) 20 | r := m["balance"].(string) 21 | newbalance, err := strconv.ParseInt(r, 10, 64) 22 | if err != nil { 23 | return errors.New("parse balance error: " + err.Error()) 24 | } 25 | 26 | if newbalance != 0 { 27 | return errors.New("darin contract failed") 28 | } 29 | 30 | return nil 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/transitions/pause.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "github.com/Zilliqa/gozilliqa-sdk/core" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) Pause() { 9 | t.LogStart("Pause") 10 | 11 | proxy,ssnlist := t.DeployAndUpgrade() 12 | 13 | // as non admin, pause 14 | ssnlist.LogContractStateJson() 15 | proxy.UpdateWallet(key2) 16 | args := []core.ContractValue{} 17 | tnx,err := proxy.Call("Pause",args,"0") 18 | t.AssertError(err) 19 | receipt := t.GetReceiptString(tnx) 20 | log.Println(receipt) 21 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))])") 22 | ssnlist.LogContractStateJson() 23 | 24 | // as admin, pause 25 | proxy.UpdateWallet(key1) 26 | tnx,err2 := proxy.Call("Pause",args,"0") 27 | if err2 != nil { 28 | t.LogError("Pause",err2) 29 | } 30 | receipt = t.GetReceiptString(tnx) 31 | log.Println(receipt) 32 | ssnlist.LogContractStateJson() 33 | 34 | t.LogEnd("Pause") 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tests/transitions/update_received_addr.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) UpdateReceiveAddr() { 6 | t.LogStart("UpdateReceiveAddr") 7 | proxy, ssnlist := t.DeployAndUpgrade() 8 | proxy.AddSSN("0x"+addr1, "xiaohuo") 9 | proxy.Unpause() 10 | 11 | ssnlist.LogContractStateJson() 12 | 13 | // as ssn operator, update receiving address 14 | newAddr := "0x" + addr2 15 | txn, err := proxy.UpdateReceiveAddr(newAddr) 16 | if err != nil { 17 | t.LogError("UpdateReceiveAddr", err) 18 | } 19 | receipt := t.GetReceiptString(txn) 20 | log.Println(receipt) 21 | state := ssnlist.LogContractStateJson() 22 | t.AssertContain(state,newAddr) 23 | 24 | // as non operator, should fail 25 | proxy.UpdateWallet(key2) 26 | txn, err1 := proxy.UpdateReceiveAddr(newAddr) 27 | t.AssertError(err1) 28 | receipt = t.GetReceiptString(txn) 29 | log.Println(receipt) 30 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -10))])") 31 | 32 | t.LogEnd("UpdateReceiveAddr") 33 | } 34 | -------------------------------------------------------------------------------- /tests/transitions/update_staking_parameters.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) UpdateStakingParameters() { 9 | t.LogStart("UpdateStakingParameters") 10 | proxy,ssnlist := t.DeployAndUpgrade() 11 | 12 | // as admin, should succeed 13 | ssnlist.LogContractStateJson() 14 | min := "100000" 15 | delegMin := "50000" 16 | txn,err1 := proxy.UpdateStakingParameters(min,delegMin) 17 | if err1 != nil { 18 | t.LogError("UpdateStakingParameters failed", err1) 19 | } 20 | receipt, _ := json.Marshal(txn.Receipt) 21 | recp := string(receipt) 22 | log.Println(recp) 23 | state := ssnlist.LogContractStateJson() 24 | t.AssertContain(state,"\"minstake\":\"100000\"") 25 | 26 | 27 | // as non admin 28 | proxy.UpdateWallet(key2) 29 | txn, err2 := proxy.UpdateStakingParameters(min,delegMin) 30 | t.AssertError(err2) 31 | receipt, _ = json.Marshal(txn.Receipt) 32 | recp = string(receipt) 33 | log.Println(recp) 34 | ssnlist.LogContractStateJson() 35 | 36 | t.LogEnd("UpdateStakingParameters") 37 | } -------------------------------------------------------------------------------- /tests/transitions/update_verifier.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | func (t *Testing) UpdateVerifier() { 8 | t.LogStart("UpdateVerifier") 9 | 10 | proxy,ssnlist := t.DeployAndUpgrade() 11 | 12 | // as admin, update verifier 13 | fakeVerifier := "0x82b142aa3d6733f8373477eca5cb2f35f240928f" 14 | ssnlist.LogContractStateJson() 15 | tnx, err := proxy.UpdateVerifier(fakeVerifier) 16 | if err != nil { 17 | t.LogError("UpdateVerifier",err) 18 | } 19 | receipt := t.GetReceiptString(tnx) 20 | log.Println(receipt) 21 | t.AssertContain(receipt, fakeVerifier) 22 | ssnlist.LogContractStateJson() 23 | 24 | 25 | // as non admin, update verifier 26 | fakeVerifier = "0xc61556c0762bd6ffd05258e083fdf70aa7537c3b" 27 | proxy.UpdateWallet(key2) 28 | tnx, err1 := proxy.UpdateVerifier(fakeVerifier) 29 | t.AssertError(err1) 30 | receipt = t.GetReceiptString(tnx) 31 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))])") 32 | log.Println(receipt) 33 | 34 | t.LogEnd("UpdateVerifier") 35 | } -------------------------------------------------------------------------------- /tests/transitions/deploy_and_upgrade.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "Zilliqa/stake-test/deploy" 5 | "github.com/Zilliqa/gozilliqa-sdk/core" 6 | "log" 7 | ) 8 | 9 | // this is a help function : ) 10 | func (t *Testing) DeployAndUpgrade() (*deploy.Proxy, *deploy.SSNList) { 11 | log.Println("start to deploy proxy contract") 12 | proxy, err := deploy.NewProxy(key1) 13 | if err != nil { 14 | t.LogError("deploy proxy error = ", err) 15 | } 16 | log.Println("deploy proxy succeed, address = ", proxy.Addr) 17 | 18 | log.Println("start to deploy ssnlist contract") 19 | ssnlist, err1 := deploy.NewSSNList(key1, proxy.Addr) 20 | if err1 != nil { 21 | t.LogError("deploy ssnlist error = ", err1) 22 | } 23 | log.Println("deploy ssnlist succeed, address = ", ssnlist.Addr) 24 | 25 | log.Println("start to upgrade") 26 | args := []core.ContractValue{ 27 | { 28 | "newImplementation", 29 | "ByStr20", 30 | "0x" + ssnlist.Addr, 31 | }, 32 | } 33 | _, err2 := proxy.Call("UpgradeTo", args,"0") 34 | if err2 != nil { 35 | t.LogError("UpgradeTo failed", err2) 36 | } 37 | log.Println("upgrade succeed") 38 | 39 | return proxy, ssnlist 40 | } 41 | -------------------------------------------------------------------------------- /tests/transitions/drain_contract_balance.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "errors" 5 | "github.com/Zilliqa/gozilliqa-sdk/core" 6 | "log" 7 | ) 8 | 9 | func (t Testing) DrainContractBalance() { 10 | t.LogStart("DrainContractBalance") 11 | 12 | proxy,ssnlist := t.DeployAndUpgrade() 13 | 14 | // unpasue 15 | proxy.Unpause() 16 | 17 | // fund 100zil first 18 | proxy.AddFunds("100000000000000") 19 | 20 | // drain 5000 21 | args := []core.ContractValue{ 22 | { 23 | "amt", 24 | "Uint128", 25 | "50000000000000", 26 | }, 27 | } 28 | 29 | // drain balance while contract is unpaused 30 | tnx,err := proxy.Call("DrainContractBalance",args,"0") 31 | t.AssertError(err) 32 | 33 | // pause contract 34 | proxy.Pause() 35 | 36 | // drain balance again 37 | tnx,err1 := proxy.Call("DrainContractBalance",args,"0") 38 | 39 | if err1 != nil { 40 | t.LogError("DrainContractBalance",err) 41 | } 42 | 43 | if ssnlist.GetBalance() != "50000000000000" { 44 | t.LogError("DrainContractBalance",errors.New("balance error")) 45 | } 46 | 47 | receipt := t.GetReceiptString(tnx) 48 | log.Println(receipt) 49 | t.LogEnd("DrainContractBalance") 50 | } 51 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_rewards_simulation.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) WithdrawStakeRewardSimulation() { 9 | t.LogStart("WithdrawStakeRewardSimulation") 10 | proxy, ssnlist := t.DeployAndUpgrade() 11 | // unpause 12 | proxy.Unpause() 13 | // set staking parameters 14 | min := "100000000000000" 15 | delegMin := "50000" 16 | proxy.UpdateStakingParameters(min,delegMin) 17 | // update verifier to addr1 18 | proxy.UpdateVerifier("0x" + addr1) 19 | // add ssn1 20 | proxy.AddSSNAfterUpgrade("0x"+addr1,"0") 21 | proxy.AddFunds("100000000000000000") 22 | // delegate stake 23 | proxy.DelegateStake("0x"+addr1, "100000000000000") 24 | result := proxy.AssignStakeRewardBatch("0x"+addr1, "52000000") 25 | for _,r := range result { 26 | fmt.Println("to see if error") 27 | fmt.Println(r.ErrMsg) 28 | } 29 | ssnlist.LogContractStateJson() 30 | // withdraw rewards 31 | txn,err2 := proxy.WithdrawStakeRewards("0x"+addr1) 32 | if err2 != nil { 33 | t.LogError("WithdrawStakeReward",err2) 34 | } 35 | receipt := t.GetReceiptString(txn) 36 | log.Println(receipt) 37 | ssnlist.LogContractStateJson() 38 | t.LogEnd("WithdrawStakeRewardSimulation") 39 | } -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | This is a collection of Javascript scripts that shows how to interact with the staking smart contract from deploying, deposit stake deposit to withdraw rewards. 3 | 4 | These scripts utilizes [Zilliqa-JavaScript-Library](https://github.com/Zilliqa/Zilliqa-JavaScript-Library) and has been tested on **NodeJS 12.9.0**. 5 | 6 | # Contents 7 | The scripts are divided into folders based on the following roles 8 | - Contract admin 9 | - Verifier 10 | - Staked seed node operator 11 | - Proxy contract admin 12 | 13 | # Requirements 14 | - NodeJS >= 10.6 15 | 16 | # Installation 17 | Install dependencies via `npm`: 18 | ``` 19 | cd javascript 20 | npm install 21 | ``` 22 | 23 | # Configuration 24 | Open the `.js` file with a text editor which you want to execute and edit the parameters accordingly: 25 | ``` 26 | const API = 'http://localhost:5555' // use https://dev-api.zilliqa.com for Dev Testnet 27 | const CHAIN_ID = 1; // use 333 for developer testnet 28 | const PRIVATE_KEY = 'd96e9eb5b782a80ea153c937fa83e5948485fbfc8b7e7c069d7b914dbc350aba'; 29 | ... 30 | ... 31 | ``` 32 | 33 | # Execution 34 | Execute a script to interact with the smart contract: 35 | ``` 36 | node deploy.js 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_amount3.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | func (t *Testing) WithDrawStakeAmount3() { 4 | t.LogStart("WithDrawStakeAmount3") 5 | // deploy 6 | proxy, ssnlist := t.DeployAndUpgrade() 7 | 8 | // unpause 9 | proxy.Unpause() 10 | // set staking parameters 11 | min := "100000000000000" 12 | min2 := "200000000000000" 13 | min3 := "300000000000000" 14 | //tenzil := "10000000000000" 15 | ssn1 := "0x"+addr1 16 | delegMin := "50000" 17 | proxy.UpdateStakingParameters(min,delegMin) 18 | // update verifier to addr1 19 | proxy.UpdateVerifier(ssn1) 20 | // add ssn1 21 | proxy.AddSSN(ssn1, "ssn1") 22 | proxy.AddFunds(min2) 23 | ssnlist.LogContractStateJson() 24 | // add delegator (addr1) to ssn1 (addr1) with min zil, make ssn active 25 | proxy.UpdateWallet(key1) 26 | proxy.DelegateStake(ssn1,min2) 27 | ssnlist.LogContractStateJson() 28 | 29 | 30 | // try withdraw more than delegate 31 | txn, err := proxy.WithdrawStakeAmt("0x" + addr1,min3) 32 | t.AssertError(err) 33 | t.LogPrettyReceipt(txn) 34 | ssnlist.LogContractStateJson() 35 | 36 | 37 | // try withdraw half 38 | txn, err1 := proxy.WithdrawStakeAmt("0x" + addr1,min) 39 | if err1 != nil { 40 | t.LogError("WithDrawStakeAmount3",err) 41 | } 42 | t.LogPrettyReceipt(txn) 43 | ssnlist.LogContractStateJson() 44 | t.LogEnd("WithDrawStakeAmount3") 45 | } 46 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ######################################################################################## 4 | # Update the values below 5 | STAKING_PRIVKEY_ADMIN="38f3715e7ef9b5a5080171dca4cb37b05eaa7e3b0d9a9427a11e021e1029525d" 6 | STAKING_PRIVKEY_VERIF="38f3715e7ef9b5a5080171dca4cb37b05eaa7e3b0d9a9427a11e021e1029525d" 7 | STAKING_ADDRESS_ADMIN="09710e00256db2e3db4b44f597f17f3d97f06318" 8 | STAKING_ADDRESS_PROXY="09710e00256db2e3db4b44f597f17f3d97f06318" 9 | STAKING_ADDRESS_SSNLIST="09710e00256db2e3db4b44f597f17f3d97f06318" 10 | STAKING_ADDRESS_VERIF="09710e00256db2e3db4b44f597f17f3d97f06318" 11 | TESTNET_API_URL="https://dev-api.zilliqa.com/" 12 | TESTNET_CHAINID="2" 13 | ######################################################################################## 14 | 15 | # Replace testnet settings in go-zli wallet file 16 | sed -i "s|\"api\":[^,]*,|\"api\":\"${TESTNET_API_URL}\",|g" ~/.zilliqa 17 | sed -i "s|\"chain_id\":[^,]*,|\"chain_id\":${TESTNET_CHAINID},|g" ~/.zilliqa 18 | 19 | # Replace admin address in proxy.json file for deploy_proxy.sh 20 | sed -i "8s|.*| \"value\": \"0x${STAKING_ADDRESS_ADMIN}\"|" proxy.json 21 | 22 | # Replace admin address and proxy address in ssnlist.json file for deploy_ssnlist.sh 23 | sed -i "8s|.*| \"value\": \"0x${STAKING_ADDRESS_ADMIN}\"|" ssnlist.json 24 | sed -i "12s|.*| \"value\": \"0x${STAKING_ADDRESS_PROXY}\"|" ssnlist.json -------------------------------------------------------------------------------- /tests/transitions/upgrade_to.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "Zilliqa/stake-test/deploy" 5 | "encoding/json" 6 | "errors" 7 | "log" 8 | "strings" 9 | 10 | "github.com/Zilliqa/gozilliqa-sdk/core" 11 | ) 12 | 13 | const failedLog = "upgradeTo FailedNotAdmin" 14 | 15 | func (t *Testing) UpgradeTo() { 16 | t.LogStart("UpgradeTo") 17 | 18 | log.Println("start to deploy proxy contract") 19 | proxy, err := deploy.NewProxy(key1) 20 | if err != nil { 21 | t.LogError("deploy proxy error = ", err) 22 | } 23 | log.Println("deploy proxy succeed, address = ", proxy.Addr) 24 | 25 | proxy.LogContractStateJson() 26 | // 1. as admin, upgrade it 27 | fakeImpl := "0x4226fe2ccbe7c67ae25a0b91414f9129a7892bd5" 28 | args := []core.ContractValue{ 29 | { 30 | "newImplementation", 31 | "ByStr20", 32 | fakeImpl, 33 | }, 34 | } 35 | 36 | _, err1 := proxy.Call("UpgradeTo", args, "0") 37 | if err1 != nil { 38 | t.LogError("UpgradeTo failed", err1) 39 | } 40 | proxy.LogContractStateJson() 41 | 42 | // 2. as non-admin, upgrade it 43 | proxy.UpdateWallet(key2) 44 | tnx, _ := proxy.Call("UpgradeTo", args, "0") 45 | receipt, _ := json.Marshal(tnx.Receipt) 46 | recp := string(receipt) 47 | log.Println(recp) 48 | if !strings.Contains(recp, failedLog) { 49 | t.LogError("UpgradeTo", errors.New("event log failed")) 50 | } 51 | proxy.LogContractStateJson() 52 | t.LogEnd("UpgradeTo") 53 | } 54 | -------------------------------------------------------------------------------- /tests/generatedAccounts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "private_key": "e40afdc148c8f169613ba1bb2f9b15186cff6e1f5ad50ddc42aae7e5d51042bb", 4 | "public_key": "02663c6e4f17b221aaa8b8599e4c7d79e96c20e669370b1b2e358bea8629ef0eeb", 5 | "address": "29cf16563fac1ad1596dfe6f333978fece9706ec", 6 | "bech_32_address": "zil19883v43l4sddzktdlehnxwtclm8fwphvrfm3s7" 7 | }, 8 | { 9 | "private_key": "8732034b0c895564d966e3df6968205211c7a2f0140b77c9e13de10c1ce77873", 10 | "public_key": "02c59f16bc98d7dff5b205ac2c2385f028d1fa005018ae1a5f30ec15e59e535fd4", 11 | "address": "e2cd74983c7a3487af3a133a3bf4e7dd76f5d928", 12 | "bech_32_address": "zil1utxhfxpu0g6g0te6zvarha88m4m0tkfg47pnuf" 13 | }, 14 | { 15 | "private_key": "70c57a0a1f9a0e2c9192f28279a491bcb30a7d0ada87eab9aa0b6afad3f31c91", 16 | "public_key": "028c68a82a3163adae44dea6eaa871b3adad766112b6db69239073c42e39566934", 17 | "address": "8bdc7e9064f3963654967fa28976aac98f002a58", 18 | "bech_32_address": "zil130w8ayry7wtrv4yk073gja42ex8sq2jcp65jp6" 19 | }, 20 | { 21 | "private_key": "243d302e971f7469cb20cc4d37c4629f0c22860667370b4d1130ae4ab1a5f4f9", 22 | "public_key": "026fa3a6c6b47d249a2e3a79211aaace5b4aaa9a6dce47a9893bccea0a290fe5bf", 23 | "address": "6e081b8cca40c585d6d69f9643faf1a545d13d63", 24 | "bech_32_address": "zil1dcyphrx2grzct4kkn7ty87h354zaz0trvnkuuj" 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /tests/transitions/assign_stake_reward.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) AssignStakeReward() { 6 | t.LogStart("AssignStakeReward") 7 | proxy, ssnlist := t.DeployAndUpgrade() 8 | // unpause 9 | proxy.Unpause() 10 | // set staking parameters 11 | min := "100000000000000" 12 | delegMin := "50000" 13 | proxy.UpdateStakingParameters(min,delegMin) 14 | // update verifier to addr2 15 | proxy.UpdateVerifier("0x" + addr2) 16 | // update verifier receiving addr to addr2 17 | proxy.UpdateVerifierRewardAddr("0x" + addr2) 18 | // add ssn1 19 | proxy.AddSSN("0x"+addr1, "ssn1") 20 | // fund ssnlist 21 | proxy.AddFunds("100000000000000") 22 | // delegate stake 23 | proxy.DelegateStake("0x"+addr1, "100000000000000") 24 | ssnlist.LogContractStateJson() 25 | 26 | // use addr2(which is verifier) to assign rewards 27 | proxy.UpdateWallet(key2) 28 | txn,err := proxy.AssignStakeReward("0x"+addr1, "52000000") 29 | if err != nil { 30 | t.LogError("AssignStakeReward",err) 31 | } 32 | receipt := t.GetReceiptString(txn) 33 | log.Println(receipt) 34 | state := ssnlist.LogContractStateJson() 35 | t.AssertContain(state,"\"lastrewardcycle\":\"2\"") 36 | t.AssertContain(state,"52000000") 37 | // use addr1 (which is not verifier) to assign rewards 38 | proxy.UpdateWallet(key1) 39 | txn,err1 := proxy.AssignStakeReward("0x"+addr1, "52000000") 40 | t.AssertError(err1) 41 | receipt = t.GetReceiptString(txn) 42 | log.Println(receipt) 43 | 44 | t.LogEnd("AssignStakeReward") 45 | } 46 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_comm.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) WithdrawComm() { 9 | t.LogStart("WithdrawComm") 10 | proxy,ssnlist := t.DeployAndUpgrade() 11 | 12 | // unpause 13 | proxy.Unpause() 14 | // set staking parameters 15 | min := "100000000000000" 16 | delegMin := "50000" 17 | proxy.UpdateStakingParameters(min,delegMin) 18 | // update verifier to addr2 19 | proxy.UpdateVerifier("0x" + addr1) 20 | // update verifier receiving addr to add1 21 | proxy.UpdateVerifierRewardAddr("0x" + addr1) 22 | // add ssn1 23 | proxy.AddSSN("0x"+addr1, "ssn1") 24 | // pause 25 | proxy.Pause() 26 | proxy.PopulateTotalStakeAmt("1000000000000000") 27 | // unpause 28 | proxy.Unpause() 29 | // delegate stake 30 | proxy.AddDelegator("0x"+addr1, "0x"+addr3, "100000000000000") 31 | proxy.AssignStakeReward("0x"+addr1, "10000000") 32 | proxy.UpdateComm("100000000") 33 | // fund ssnlist 34 | proxy.AddFunds("100000000000000") 35 | proxy.AssignStakeReward("0x"+addr1, "10000000") 36 | ssnlist.LogContractStateJson() 37 | 38 | txn,err := proxy.WithdrawComm("0x"+addr1) 39 | if err != nil { 40 | t.LogError("WithdrawComm",err) 41 | } 42 | receipt, _ := json.Marshal(txn.Receipt) 43 | recp := string(receipt) 44 | log.Println(recp) 45 | ssnlist.LogContractStateJson() 46 | 47 | proxy.UpdateWallet(key2) 48 | txn,err1 := proxy.WithdrawComm("0x"+addr1) 49 | t.AssertError(err1) 50 | ssnlist.LogContractStateJson() 51 | 52 | t.LogEnd("WithdrawComm") 53 | } -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_rewards2.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | // case for inactive => delegate => active => withdraw(one) => withdraw(none) => reward => reward => withdraw(two) 6 | func (t *Testing) WithdrawStakeReward2() { 7 | t.LogStart("WithdrawStakeReward2") 8 | proxy, ssnlist := t.DeployAndUpgrade() 9 | // unpause 10 | proxy.Unpause() 11 | // set staking parameters 12 | min := "100000000000000" 13 | delegMin := "50000" 14 | proxy.UpdateStakingParameters(min,delegMin) 15 | // update verifier to addr1 16 | proxy.UpdateVerifier("0x" + addr1) 17 | // update verifier receiving addr to add1 18 | proxy.UpdateVerifierRewardAddr("0x" + addr1) 19 | // add ssn1 20 | proxy.AddSSNAfterUpgrade("0x"+addr1,"0") 21 | proxy.AddFunds("1000000000000") 22 | // delegate stake 23 | proxy.DelegateStake("0x"+addr1, "100000000000000") 24 | proxy.AssignStakeReward("0x"+addr1, "52000000") 25 | ssnlist.LogContractStateJson() 26 | 27 | // withdraw rewards 28 | txn,err2 := proxy.WithdrawStakeRewards("0x"+addr1) 29 | if err2 != nil { 30 | t.LogError("WithdrawStakeReward2",err2) 31 | } 32 | receipt := t.GetReceiptString(txn) 33 | log.Println(receipt) 34 | ssnlist.LogContractStateJson() 35 | 36 | proxy.WithdrawStakeRewards("0x"+addr1) 37 | ssnlist.LogContractStateJson() 38 | 39 | proxy.AssignStakeReward("0x"+addr1, "52000000") 40 | proxy.AssignStakeReward("0x"+addr1, "52000000") 41 | proxy.WithdrawStakeRewards("0x"+addr1) 42 | ssnlist.LogContractStateJson() 43 | 44 | t.LogEnd("WithdrawStakeReward2") 45 | } -------------------------------------------------------------------------------- /tests/transitions/update_admin.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "github.com/Zilliqa/gozilliqa-sdk/core" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) UpdateAdmin() { 9 | t.LogStart("UpdateAdmin") 10 | proxy, ssnlist := t.DeployAndUpgrade() 11 | 12 | // as admin, propose new admin to addr2 13 | ssnlist.LogContractStateJson() 14 | args := []core.ContractValue{{ 15 | "new_admin", 16 | "ByStr20", 17 | "0x" + addr2, 18 | }} 19 | tnx, err := proxy.Call("UpdateAdmin", args,"0") 20 | if err != nil { 21 | t.LogError("UpdateAdmin", err) 22 | } 23 | receipt := t.GetReceiptString(tnx) 24 | log.Println(receipt) 25 | t.AssertContain(receipt, addr2) 26 | ssnlist.LogContractStateJson() 27 | 28 | // as origin admin, propose again 29 | args = []core.ContractValue{{ 30 | "new_admin", 31 | "ByStr20", 32 | "0x" + addr2, 33 | }} 34 | tnx, err2 := proxy.Call("UpdateAdmin", args,"0") 35 | if err2 != nil { 36 | t.LogError("UpdateAdmin", err2) 37 | } 38 | 39 | // addr2 claim to be admin 40 | proxy.UpdateWallet(key2) 41 | tnx, err3 := proxy.ClaimAdmin() 42 | if err3 != nil { 43 | t.LogError("ClaimAdmin", err3) 44 | } 45 | 46 | // addr1 (as non-admin), update admin 47 | proxy.UpdateWallet(key1) 48 | tnx, err4 := proxy.Call("UpdateAdmin", args,"0") 49 | t.AssertError(err4) 50 | receipt = t.GetReceiptString(tnx) 51 | log.Println(receipt) 52 | t.AssertContain(receipt,"Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))]") 53 | ssnlist.LogContractStateJson() 54 | 55 | t.LogEnd("UpdateAdmin") 56 | 57 | } 58 | -------------------------------------------------------------------------------- /tests/transitions/change_proxy_admin.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "Zilliqa/stake-test/deploy" 5 | "encoding/json" 6 | "log" 7 | 8 | "github.com/Zilliqa/gozilliqa-sdk/core" 9 | ) 10 | 11 | const adminChanged = "ChangeProxyAdmin" 12 | const adminNotChanged = "ChangeProxyAdmin FailedNotAdmin" 13 | 14 | func (t *Testing) ChangeProxyAdmin() { 15 | t.LogStart("ChangeProxyAdmin") 16 | log.Println("start to deploy proxy contract") 17 | proxy, err := deploy.NewProxy(key1) 18 | if err != nil { 19 | t.LogError("deploy proxy error = ", err) 20 | } 21 | log.Println("deploy proxy succeed, address = ", proxy.Addr) 22 | 23 | proxy.LogContractStateJson() 24 | // 1. as admin, change proxy admin 25 | newAdmin := "0x4226fe2ccbe7c67ae25a0b91414f9129a7892bd5" 26 | args := []core.ContractValue{ 27 | { 28 | "newAdmin", 29 | "ByStr20", 30 | newAdmin, 31 | }, 32 | } 33 | 34 | txn, err1 := proxy.Call("ChangeProxyAdmin", args, "0") 35 | if err1 != nil { 36 | t.LogError("ChangeProxyAdmin failed", err1) 37 | } 38 | 39 | receipt, _ := json.Marshal(txn.Receipt) 40 | recp := string(receipt) 41 | t.AssertContain(recp, adminChanged) 42 | log.Println(recp) 43 | proxy.LogContractStateJson() 44 | 45 | // 2. as non-admin, change proxy admin 46 | proxy.UpdateWallet(key2) 47 | tnx, _ := proxy.Call("ChangeProxyAdmin", args, "0") 48 | receipt, _ = json.Marshal(tnx.Receipt) 49 | recp = string(receipt) 50 | log.Println(recp) 51 | t.AssertContain(recp, adminNotChanged) 52 | proxy.LogContractStateJson() 53 | 54 | t.LogEnd("ChangeProxyAdmin") 55 | } 56 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_rewards3.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | // case for active => delegate => reward => withdraw(non) => reward => withdraw 6 | func (t *Testing) WithdrawStakeReward3() { 7 | t.LogStart("WithdrawStakeReward3") 8 | proxy, ssnlist := t.DeployAndUpgrade() 9 | // unpause 10 | proxy.Unpause() 11 | // set staking parameters 12 | min := "100000000000000" 13 | delegMin := "50000" 14 | proxy.UpdateStakingParameters(min,delegMin) 15 | // update verifier to addr1 16 | proxy.UpdateVerifier("0x" + addr1) 17 | // update verifier receiving addr to add1 18 | proxy.UpdateVerifierRewardAddr("0x" + addr1) 19 | // add ssn1 20 | proxy.AddSSNAfterUpgrade("0x"+addr1,"100000000000000") 21 | ssnlist.LogContractStateJson() 22 | 23 | // delegate stake 24 | proxy.DelegateStake("0x"+addr1, "100000000000000") 25 | proxy.AssignStakeReward("0x"+addr1, "52000000") 26 | proxy.AddFunds("1000000000000") 27 | ssnlist.LogContractStateJson() 28 | 29 | // withdraw rewards 30 | txn,err2 := proxy.WithdrawStakeRewards("0x"+addr1) 31 | if err2 != nil { 32 | t.LogError("WithdrawStakeReward3",err2) 33 | } 34 | 35 | receipt := t.GetReceiptString(txn) 36 | log.Println(receipt) 37 | ssnlist.LogContractStateJson() 38 | 39 | proxy.AssignStakeReward("0x"+addr1, "52000000") 40 | txn,err3 := proxy.WithdrawStakeRewards("0x"+addr1) 41 | if err3 != nil { 42 | t.LogError("WithdrawStakeReward3",err2) 43 | } 44 | 45 | receipt = t.GetReceiptString(txn) 46 | log.Println(receipt) 47 | ssnlist.LogContractStateJson() 48 | 49 | 50 | t.LogEnd("WithdrawStakeReward3") 51 | } -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_rewards.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) WithdrawStakeReward() { 9 | t.LogStart("WithdrawStakeReward") 10 | proxy, ssnlist := t.DeployAndUpgrade() 11 | // unpause 12 | proxy.Unpause() 13 | // set staking parameters 14 | min := "100000000000000" 15 | delegMin := "50000" 16 | proxy.UpdateStakingParameters(min,delegMin) 17 | // update verifier to addr1 18 | proxy.UpdateVerifier("0x" + addr1) 19 | // update verifier receiving addr to add1 20 | proxy.UpdateVerifierRewardAddr("0x" + addr1) 21 | // add ssn1 22 | proxy.AddSSNAfterUpgrade("0x"+addr1,"200000000000000") 23 | proxy.AddFunds("1000000000000") 24 | proxy.AssignStakeReward("0x"+addr1, "52000000") 25 | // delegate stake 26 | proxy.DelegateStake("0x"+addr1, "100000000000000") 27 | proxy.AssignStakeReward("0x"+addr1, "52000000") 28 | ssnlist.LogContractStateJson() 29 | proxy.AssignStakeReward("0x"+addr1, "52000000") 30 | // delegator again 31 | proxy.DelegateStake("0x"+addr1, "100000000000000") 32 | proxy.AssignStakeReward("0x"+addr1, "52000000") 33 | ssnlist.LogContractStateJson() 34 | // reward 3 more 35 | result := proxy.AssignStakeRewardBatch("0x"+addr1, "52000000") 36 | for _,r := range result { 37 | fmt.Println("to see if error") 38 | fmt.Println(r.ErrMsg) 39 | } 40 | ssnlist.LogContractStateJson() 41 | // withdraw rewards 42 | txn,err2 := proxy.WithdrawStakeRewards("0x"+addr1) 43 | if err2 != nil { 44 | t.LogError("WithdrawStakeReward",err2) 45 | } 46 | receipt := t.GetReceiptString(txn) 47 | log.Println(receipt) 48 | ssnlist.LogContractStateJson() 49 | t.LogEnd("WithdrawStakeReward") 50 | } -------------------------------------------------------------------------------- /tests/transitions/add_ssn.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) AddSSN() { 6 | t.LogStart("AddSSN") 7 | proxy,ssnlist := t.DeployAndUpgrade() 8 | 9 | ssnlist.LogContractStateJson() 10 | // as admin 11 | txn,err := proxy.AddSSN("0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82","xiaohuo") 12 | if err != nil { 13 | t.LogError("AddSSN",err) 14 | } 15 | receipt := t.GetReceiptString(txn) 16 | log.Println(receipt) 17 | state := ssnlist.LogContractStateJson() 18 | t.AssertContain(state,"{\"argtypes\":[],\"arguments\":[],\"constructor\":\"False\"}") 19 | t.AssertContain(state,"{\"argtypes\":[],\"arguments\":[{\"argtypes\":[],\"arguments\":[],\"constructor\":\"False\"},\"0\",\"0\",\"xiaohuo\",\"fakeurl\",\"fakeapi\",\"0\",\"0\",\"0\",\"0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82\"") 20 | t.LogEnd("AddSSN") 21 | 22 | // as admin, add again, should fail 23 | txn,err1 := proxy.AddSSN("0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82","xiaohuo") 24 | t.AssertError(err1) 25 | receipt = t.GetReceiptString(txn) 26 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -11))])") 27 | log.Println(receipt) 28 | state = ssnlist.LogContractStateJson() 29 | 30 | // as non admin, add another, should fail 31 | proxy.UpdateWallet(key2) 32 | txn,err2 := proxy.AddSSN("0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed81","xiaohuo1") 33 | t.AssertError(err2) 34 | receipt = t.GetReceiptString(txn) 35 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))])") 36 | log.Println(receipt) 37 | ssnlist.LogContractStateJson() 38 | 39 | t.LogEnd("AddSSN") 40 | } 41 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_amount2.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | func (t *Testing) WithDrawStakeAmount2() { 4 | t.LogStart("WithDrawStakeAmount2") 5 | // deploy 6 | proxy, ssnlist := t.DeployAndUpgrade() 7 | 8 | // unpause 9 | proxy.Unpause() 10 | // set staking parameters 11 | min := "100000000000000" 12 | min2 := "200000000000000" 13 | //tenzil := "10000000000000" 14 | ssn1 := "0x"+addr1 15 | delegMin := "50000" 16 | proxy.UpdateStakingParameters(min,delegMin) 17 | // update verifier to addr1 18 | proxy.UpdateVerifier(ssn1) 19 | // update verifier receiving addr to addr2 20 | proxy.UpdateVerifierRewardAddr("0x" + addr2) 21 | // add ssn1 22 | proxy.AddSSN(ssn1, "ssn1") 23 | proxy.AddFunds(min) 24 | ssnlist.LogContractStateJson() 25 | // add delegator (addr1) to ssn1 (addr1) with min zil, make ssn active 26 | proxy.UpdateWallet(key1) 27 | proxy.DelegateStake(ssn1,min) 28 | // delegate again, comes to buffered deposit 29 | proxy.DelegateStake(ssn1,min) 30 | ssnlist.LogContractStateJson() 31 | 32 | // try withdraw, should fail 33 | txn, err := proxy.WithdrawStakeAmt("0x" + addr1,min2) 34 | t.AssertError(err) 35 | t.LogPrettyReceipt(txn) 36 | 37 | // reward 38 | proxy.AssignStakeReward(ssn1, "52000000") 39 | 40 | // try withdraw, should fail (because of rewards) 41 | txn, err1 := proxy.WithdrawStakeAmt(ssn1,min2) 42 | t.AssertError(err1) 43 | t.LogPrettyReceipt(txn) 44 | 45 | // withdraw rewards 46 | proxy.WithdrawStakeRewards(ssn1) 47 | 48 | // withdraw amount 49 | txn, err2 := proxy.WithdrawStakeAmt(ssn1,min2) 50 | if err2 != nil { 51 | t.LogError("WithDrawStakeAmount2",err2) 52 | } 53 | t.LogPrettyReceipt(txn) 54 | t.LogEnd("WithDrawStakeAmount2") 55 | } 56 | -------------------------------------------------------------------------------- /.github/workflows/workflow.yml: -------------------------------------------------------------------------------- 1 | name: Typecheck contracts 2 | 3 | on: 4 | - pull_request 5 | - push 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: [ubuntu-18.04, ubuntu-20.04] 13 | ocaml-version: 14 | - 4.08.1 15 | 16 | runs-on: ${{ matrix.os }} 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v2 21 | 22 | - name: Try to restore opam cache 23 | if: runner.os != 'Windows' 24 | id: opam-cache 25 | uses: actions/cache@v2 26 | with: 27 | path: "~/.opam" 28 | key: ${{ matrix.os }}-${{ matrix.ocaml-version }} 29 | 30 | - name: Use OCaml ${{ matrix.ocaml-version }} 31 | uses: avsm/setup-ocaml@v1 32 | with: 33 | ocaml-version: ${{ matrix.ocaml-version }} 34 | 35 | - name: boost 36 | run: sudo apt-get update && sudo apt-get install -yq libboost-system-dev libboost-test-dev 37 | 38 | - run: opam pin add scilla.dev git+https://github.com/Zilliqa/scilla\#master --no-action 39 | 40 | - run: opam depext scilla --yes 41 | 42 | - run: opam install --verbose scilla 43 | 44 | - run: opam exec -- scilla-checker -gaslimit 10000 -libdir "$(opam var scilla:lib)/stdlib" contracts/gzil.scilla 45 | - if: ${{ always() }} 46 | run: opam exec -- scilla-checker -gaslimit 10000 -libdir "$(opam var scilla:lib)/stdlib" contracts/multisig_wallet.scilla 47 | - if: ${{ always() }} 48 | run: opam exec -- scilla-checker -gaslimit 10000 -libdir "$(opam var scilla:lib)/stdlib" contracts/proxy.scilla 49 | - if: ${{ always() }} 50 | run: opam exec -- scilla-checker -gaslimit 10000 -libdir "$(opam var scilla:lib)/stdlib" contracts/ssnlist.scilla 51 | -------------------------------------------------------------------------------- /tests/transitions/testing.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/Zilliqa/gozilliqa-sdk/transaction" 6 | "log" 7 | "strings" 8 | ) 9 | 10 | const key1 = "e40afdc148c8f169613ba1bb2f9b15186cff6e1f5ad50ddc42aae7e5d51042bb" 11 | const addr1 = "29cf16563fac1ad1596dfe6f333978fece9706ec" 12 | const key2 = "8732034b0c895564d966e3df6968205211c7a2f0140b77c9e13de10c1ce77873" 13 | const addr2 = "e2cd74983c7a3487af3a133a3bf4e7dd76f5d928" 14 | const key3 = "70c57a0a1f9a0e2c9192f28279a491bcb30a7d0ada87eab9aa0b6afad3f31c91" 15 | const addr3 = "8bdc7e9064f3963654967fa28976aac98f002a58" 16 | const key4 = "243d302e971f7469cb20cc4d37c4629f0c22860667370b4d1130ae4ab1a5f4f9" 17 | const addr4 = "6e081b8cca40c585d6d69f9643faf1a545d13d63" 18 | 19 | type Testing struct { 20 | } 21 | 22 | func NewTesting() *Testing { 23 | return &Testing{} 24 | } 25 | 26 | func (t *Testing) LogStart(tag string) { 27 | log.Printf("start to test %s\n", tag) 28 | } 29 | 30 | func (t *Testing) LogEnd(tag string) { 31 | log.Printf("end to test %s\n", tag) 32 | } 33 | 34 | func (t *Testing) LogError(tag string, err error) { 35 | log.Fatalf("failed at %s, err = %s\n", tag, err.Error()) 36 | } 37 | 38 | func (t *Testing) AssertContain(s1, s2 string) { 39 | if !strings.Contains(s1, s2) { 40 | log.Println(s1) 41 | log.Println(s2) 42 | log.Fatal("assert failed") 43 | } 44 | } 45 | 46 | func (t *Testing) AssertError(err error) { 47 | if err == nil { 48 | log.Fatal("assert error failed") 49 | } 50 | } 51 | 52 | func (t *Testing) GetReceiptString(tnx *transaction.Transaction) string { 53 | receipt, _ := json.Marshal(tnx.Receipt) 54 | return string(receipt) 55 | } 56 | 57 | func (t *Testing) LogPrettyReceipt(tnx *transaction.Transaction) { 58 | data,_ := json.MarshalIndent(tnx.Receipt,""," ") 59 | log.Println(string(data)) 60 | } 61 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/pause.js: -------------------------------------------------------------------------------- 1 | /* 2 | * pause 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = 'd96e9eb5b782a80ea153c937fa83e5948485fbfc8b7e7c069d7b914dbc350aba'; // admin 12 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 13 | 14 | const zilliqa = new Zilliqa(API); 15 | const MSG_VERSION = 1; 16 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 17 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 18 | 19 | 20 | async function main() { 21 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 22 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 23 | console.log("Your account address is: %o", `${address}`); 24 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 25 | 26 | console.log("------------------------ begin pause ------------------------\n"); 27 | try { 28 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 29 | const callTx = await contract.call( 30 | 'pause', 31 | [], 32 | { 33 | version: VERSION, 34 | amount: new BN(0), 35 | gasPrice: GAS_PRICE, 36 | gasLimit: Long.fromNumber(10000), 37 | }, 38 | 33, 39 | 1000, 40 | true 41 | ); 42 | console.log("transaction: %o", callTx.id); 43 | console.log(JSON.stringify(callTx.receipt, null, 4)); 44 | } catch (err) { 45 | console.log(err); 46 | } 47 | console.log("------------------------ end pause ------------------------\n"); 48 | } 49 | 50 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/unpause.js: -------------------------------------------------------------------------------- 1 | /* 2 | * unpause 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = 'd96e9eb5b782a80ea153c937fa83e5948485fbfc8b7e7c069d7b914dbc350aba'; // admin 12 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 13 | 14 | const zilliqa = new Zilliqa(API); 15 | const MSG_VERSION = 1; 16 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 17 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 18 | 19 | 20 | async function main() { 21 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 22 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 23 | console.log("Your account address is: %o", `${address}`); 24 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 25 | 26 | console.log("------------------------ begin unpause ------------------------\n"); 27 | try { 28 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 29 | const callTx = await contract.call( 30 | 'unpause', 31 | [], 32 | { 33 | version: VERSION, 34 | amount: new BN(0), 35 | gasPrice: GAS_PRICE, 36 | gasLimit: Long.fromNumber(10000) 37 | }, 38 | 33, 39 | 1000, 40 | true 41 | ); 42 | console.log("transaction: %o", callTx.id); 43 | console.log(JSON.stringify(callTx.receipt, null, 4)); 44 | 45 | } catch (err) { 46 | console.log(err); 47 | } 48 | console.log("------------------------ end unpause ------------------------\n"); 49 | } 50 | 51 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/get_stake_rewards.js: -------------------------------------------------------------------------------- 1 | /* 2 | * get the stake rewards 3 | */ 4 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 5 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 6 | 7 | // change the following parameters 8 | const API = 'http://localhost:5555' 9 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // private key of staker 10 | const STAKING_PROXY_ADDR = toBech32Address("0xF8AE69E4d0a4f073Bd2223a042ce89226E6d3663"); // checksum proxy address 11 | 12 | const zilliqa = new Zilliqa(API); 13 | 14 | async function main() { 15 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 16 | const address = getAddressFromPrivateKey(PRIVATE_KEY).toLowerCase(); 17 | console.log("Your account address is: %o", `${address}`); 18 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 19 | 20 | console.log("------------------------ begin get stake rewards amount ------------------------\n"); 21 | try { 22 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 23 | const state = await contract.getState(); 24 | const implAddress = state.implementation; 25 | 26 | const implContract = zilliqa.contracts.at(toBech32Address(implAddress)); 27 | const implState = await implContract.getState(); 28 | 29 | if (Object.keys(implState.ssnlist).length === 0) { 30 | console.error("SSN list is empty"); 31 | } else if (!implState.ssnlist.hasOwnProperty(address)) { 32 | console.error("No such SSN node: %o", address); 33 | } else { 34 | const arguments = implState.ssnlist[address].arguments; 35 | const rewards = arguments[2]; 36 | console.log("Stake rewards for %o: %o", address, rewards); 37 | } 38 | 39 | } catch (err) { 40 | console.log(err); 41 | } 42 | console.log("------------------------ end get stake rewards amount ------------------------\n"); 43 | } 44 | 45 | main(); -------------------------------------------------------------------------------- /tests/transitions/assign_stake_reward2.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) AssignStakeReward2() { 6 | t.LogStart("AssignStakeReward2") 7 | proxy, ssnlist := t.DeployAndUpgrade() 8 | // unpause 9 | proxy.Unpause() 10 | // set staking parameters 11 | min := "100" 12 | delegMin := "10" 13 | proxy.UpdateStakingParameters(min,delegMin) 14 | // update verifier to addr2 15 | proxy.UpdateVerifier("0x" + addr2) 16 | // update verifier receiving addr to addr2 17 | proxy.UpdateVerifierRewardAddr("0x" + addr2) 18 | // add ssn1 19 | proxy.AddSSN("0x"+addr1, "ssn1") 20 | // add ssn2 21 | proxy.AddSSN("0x"+addr2, "ssn2") 22 | // fund ssnlist 23 | proxy.AddFunds("10000000000") 24 | 25 | ssn1 := "0x"+addr1 26 | ssn2 := "0x"+addr2 27 | 28 | 29 | // for ssn1, deleg1:10, deleg2:100 30 | proxy.UpdateWallet(key1) 31 | proxy.DelegateStake(ssn1,"10") 32 | proxy.UpdateWallet(key2) 33 | proxy.DelegateStake(ssn1,"100") 34 | 35 | // for ssn2, deleg1:10, deleg2:100, deleg3:10 36 | proxy.UpdateWallet(key1) 37 | proxy.DelegateStake(ssn2,"20") 38 | proxy.UpdateWallet(key2) 39 | proxy.DelegateStake(ssn2,"100") 40 | ssnlist.LogContractStateJson() 41 | 42 | proxy.UpdateWallet(key2) 43 | // reward ssn1 44 | txn, err := proxy.AssignStakeReward3(ssn1, "100000",ssn2,"100000") 45 | if err != nil { 46 | t.LogError("AssignStakeReward2", err) 47 | } 48 | receipt := t.GetReceiptString(txn) 49 | log.Println(receipt) 50 | 51 | // deleg2 withdraw from ssn1 and ssn2 52 | proxy.UpdateWallet(key2) 53 | proxy.WithdrawStakeRewards(ssn1) 54 | proxy.WithdrawStakeRewards(ssn2) 55 | 56 | // as non-verifier 57 | proxy.UpdateWallet(key1) 58 | txn, err2 := proxy.AssignStakeReward("0x"+addr1, "10000000") 59 | t.AssertError(err2) 60 | receipt = t.GetReceiptString(txn) 61 | log.Println(receipt) 62 | ssnlist.LogContractStateJson() 63 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -2))])") 64 | t.LogEnd("AssignStakeReward2") 65 | } 66 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/get_stake_amount.js: -------------------------------------------------------------------------------- 1 | /* 2 | * get the amount deposited in the stake 3 | */ 4 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 5 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 6 | 7 | // change the following parameters 8 | const API = 'http://localhost:5555' 9 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // private key of staker 10 | const STAKING_PROXY_ADDR = toBech32Address("0xF8AE69E4d0a4f073Bd2223a042ce89226E6d3663"); // checksum proxy address 11 | 12 | const zilliqa = new Zilliqa(API); 13 | 14 | async function main() { 15 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 16 | const address = getAddressFromPrivateKey(PRIVATE_KEY).toLowerCase(); 17 | console.log("Your account address is: %o", `${address}`); 18 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 19 | 20 | console.log("------------------------ begin get stake amount ------------------------\n"); 21 | try { 22 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 23 | const state = await contract.getState(); 24 | const implAddress = state.implementation; 25 | 26 | const implContract = zilliqa.contracts.at(toBech32Address(implAddress)); 27 | const implState = await implContract.getState(); 28 | 29 | if (Object.keys(implState.ssnlist).length === 0) { 30 | console.error("SSN list is empty"); 31 | } else if (!implState.ssnlist.hasOwnProperty(address)) { 32 | console.error("No such SSN node: %o", address); 33 | } else { 34 | const arguments = implState.ssnlist[address].arguments; 35 | const stakeAmount = arguments[1]; 36 | console.log("Stake amount for %o: %o", address, stakeAmount); 37 | } 38 | 39 | } catch (err) { 40 | console.log(err); 41 | } 42 | console.log("------------------------ end get stake amount ------------------------\n"); 43 | } 44 | 45 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/add_funds.js: -------------------------------------------------------------------------------- 1 | /* 2 | * deposit funds 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; 12 | const STAKING_PROXY_ADDR = toBech32Address("0x35C36cEC66a7f5f5393f8b84eB56F4bd552dDb87"); // checksum proxy address 13 | const FUNDS = units.toQa('4000', units.Units.Zil); // deposit amount in ZIL converted to Qa 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin deposit funds ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'AddFunds', 32 | [], 33 | { 34 | version: VERSION, 35 | amount: new BN(FUNDS), 36 | gasPrice: GAS_PRICE, 37 | gasLimit: Long.fromNumber(10000) 38 | }, 39 | 33, 40 | 1000, 41 | true 42 | ); 43 | console.log("transaction: %o", callTx.id); 44 | console.log(JSON.stringify(callTx.receipt, null, 4)); 45 | 46 | } catch (err) { 47 | console.log(err); 48 | } 49 | console.log("------------------------ end deposit funds ------------------------\n"); 50 | } 51 | 52 | main(); -------------------------------------------------------------------------------- /phase0/scripts/Java/src/test/java/com/zilliqa/staking/SSNOperatorTest.java: -------------------------------------------------------------------------------- 1 | package com.zilliqa.staking; 2 | 3 | import org.junit.Test; 4 | 5 | public class SSNOperatorTest { 6 | 7 | private static String api = "https://dev-api.zilliqa.com/"; 8 | private static int chainId = 333; 9 | private static String ssnPrivateKey = ""; 10 | private static String proxyAddress = ""; 11 | SSNOperator ssnOperator = new SSNOperator(api, chainId, ssnPrivateKey, proxyAddress); 12 | 13 | public SSNOperatorTest() throws Exception { 14 | } 15 | 16 | 17 | @Test 18 | public void stakeDeposit() throws Exception { 19 | String tx = ssnOperator.stakeDeposit("1000", 100, 3); 20 | System.out.println(tx); 21 | } 22 | 23 | @Test 24 | public void withdrawStakeAmount() throws Exception { 25 | String tx = ssnOperator.withdrawStakeAmount("1000", 100, 3); 26 | System.out.println(tx); 27 | } 28 | 29 | @Test 30 | public void withdrawStakeReward() throws Exception { 31 | String tx = ssnOperator.withdrawStakeRewards(100, 3); 32 | System.out.println(tx); 33 | } 34 | 35 | @Test 36 | public void getStakeAmount() throws Exception { 37 | String state = ssnOperator.getStakeAmount(); 38 | System.out.println(state); 39 | } 40 | 41 | @Test 42 | public void getStakeBufferedAmount() throws Exception { 43 | String state = ssnOperator.getStakeBufferedAmount(); 44 | System.out.println(state); 45 | } 46 | 47 | @Test 48 | public void getStakeRewards() throws Exception { 49 | String state = ssnOperator.getStakeRewards(); 50 | System.out.println(state); 51 | } 52 | 53 | @Test 54 | public void getActiveStatue() throws Exception { 55 | System.out.println(ssnOperator.getActiveStatus()); 56 | } 57 | 58 | @Test 59 | public void getNodeStatus() throws Exception { 60 | System.out.println(ssnOperator.getNodeStatus("https://dev-api.zilliqa.com",10)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/withdraw_stake_rewards.js: -------------------------------------------------------------------------------- 1 | /* 2 | * withdraw stake rewards 3 | * used by ssn 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // ssn private key 13 | const STAKING_PROXY_ADDR = toBech32Address("0xDB5Dc7118765A84B6c6A582280fA37A1DD2d9f69"); // checksum proxy address 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin withdraw stake rewards ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'withdraw_stake_rewards', 32 | [], 33 | { 34 | version: VERSION, 35 | amount: new BN(0), 36 | gasPrice: GAS_PRICE, 37 | gasLimit: Long.fromNumber(10000) 38 | }, 39 | 33, 40 | 1000, 41 | true 42 | ); 43 | console.log("transaction: %o", callTx.id); 44 | console.log(JSON.stringify(callTx.receipt, null, 4)); 45 | 46 | } catch (err) { 47 | console.log(err); 48 | } 49 | console.log("------------------------ end withdraw stake rewards ------------------------\n"); 50 | } 51 | 52 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/drain_contract_balance.js: -------------------------------------------------------------------------------- 1 | /* 2 | * drain contract balance 3 | * Used by current admin only 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'd96e9eb5b782a80ea153c937fa83e5948485fbfc8b7e7c069d7b914dbc350aba'; // admin 13 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin drain contract balance ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'drain_contract_balance', 32 | [], 33 | { 34 | version: VERSION, 35 | amount: new BN(0), 36 | gasPrice: GAS_PRICE, 37 | gasLimit: Long.fromNumber(10000) 38 | }, 39 | 33, 40 | 1000, 41 | true 42 | ); 43 | console.log("transaction: %o", callTx.id); 44 | console.log(JSON.stringify(callTx.receipt, null, 4)); 45 | 46 | } catch (err) { 47 | console.log(err); 48 | } 49 | console.log("------------------------ end drain contract balance ------------------------\n"); 50 | } 51 | 52 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/get_stake_buffered_amount.js: -------------------------------------------------------------------------------- 1 | /* 2 | * get the buffered amount 3 | */ 4 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 5 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 6 | 7 | // change the following parameters 8 | const API = 'http://localhost:5555' 9 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // private key of staker 10 | const STAKING_PROXY_ADDR = toBech32Address("0xF8AE69E4d0a4f073Bd2223a042ce89226E6d3663"); // checksum proxy address 11 | 12 | const zilliqa = new Zilliqa(API); 13 | 14 | async function main() { 15 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 16 | const address = getAddressFromPrivateKey(PRIVATE_KEY).toLowerCase(); 17 | console.log("Your account address is: %o", `${address}`); 18 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 19 | 20 | console.log("------------------------ begin get stake buffered amount ------------------------\n"); 21 | try { 22 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 23 | const state = await contract.getState(); 24 | const implAddress = state.implementation; 25 | 26 | const implContract = zilliqa.contracts.at(toBech32Address(implAddress)); 27 | const implState = await implContract.getState(); 28 | 29 | if (Object.keys(implState.ssnlist).length === 0) { 30 | console.error("SSN list is empty"); 31 | } else if (!implState.ssnlist.hasOwnProperty(address)) { 32 | console.error("No such SSN node: %o", address); 33 | } else { 34 | const arguments = implState.ssnlist[address].arguments; 35 | const bufferedStakeAmount = arguments[5]; 36 | console.log("Buffered stake amount for %o: %o", address, bufferedStakeAmount); 37 | } 38 | 39 | } catch (err) { 40 | console.log(err); 41 | } 42 | console.log("------------------------ end get stake buffered amount ------------------------\n"); 43 | } 44 | 45 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/stake_deposit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * stake deposit 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // private key of staker 12 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 13 | const STAKE_AMOUNT = units.toQa('100', units.Units.Zil); // stake amount defined in Zil converted to Qa 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | async function main() { 21 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 22 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 23 | console.log("Your account address is: %o", `${address}`); 24 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 25 | 26 | console.log("------------------------ begin stake deposit ------------------------\n"); 27 | try { 28 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 29 | const callTx = await contract.call( 30 | 'stake_deposit', 31 | [], 32 | { 33 | version: VERSION, 34 | amount: new BN(STAKE_AMOUNT), 35 | gasPrice: GAS_PRICE, 36 | gasLimit: Long.fromNumber(10000) 37 | }, 38 | 33, 39 | 1000, 40 | true 41 | ); 42 | console.log("transaction: %o", callTx.id); 43 | console.log(JSON.stringify(callTx.receipt, null, 4)); 44 | 45 | } catch (err) { 46 | console.log(err); 47 | } 48 | console.log("------------------------ end stake deposit ------------------------\n"); 49 | } 50 | 51 | main(); -------------------------------------------------------------------------------- /phase0/tests/transitions/update_min_stake.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "strings" 10 | ) 11 | 12 | func (p *Proxy) UpdateMinStake(valid, invalid string) { 13 | err := p.updateMinStake(invalid,"1000000000") 14 | if err == nil { 15 | panic("update min stake with invalid key failed") 16 | } 17 | 18 | fmt.Println("update min stake with invalid key succeed") 19 | 20 | err2 := p.updateMinStake(valid,"1000000000") 21 | if err2 != nil { 22 | panic("update min stake with valid key failed") 23 | } 24 | 25 | fmt.Println("update min stake with valid key succeed") 26 | 27 | } 28 | 29 | func (p *Proxy) updateMinStake(private string, stakeNum string) error { 30 | if err0 := p.unpause(private); err0 != nil { 31 | panic("unpause with valid account failed") 32 | } 33 | 34 | proxy, _ := bech32.ToBech32Address(p.Addr) 35 | parameters := []contract2.Value{ 36 | { 37 | VName: "min_stake", 38 | Type: "Uint128", 39 | Value: stakeNum, 40 | }, 41 | } 42 | args, _ := json.Marshal(parameters) 43 | if err2, output := ExecZli("contract", "call", 44 | "-k", private, 45 | "-a", proxy, 46 | "-t", "update_minstake", 47 | "-f", "true", 48 | "-r", string(args)); err2 != nil { 49 | return errors.New("call transition error: " + err2.Error()) 50 | } else { 51 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 52 | fmt.Println("transaction id = ", tx) 53 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 54 | receipt := payload["receipt"].(map[string]interface{}) 55 | success := receipt["success"].(bool) 56 | if success { 57 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 58 | minstake := res["minstake"].(string) 59 | if minstake == stakeNum { 60 | return nil 61 | } else { 62 | return errors.New("state failed") 63 | } 64 | 65 | } else { 66 | return errors.New("transaction failed") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /phase0/tests/transitions/update_max_stake.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "strings" 10 | ) 11 | 12 | func (p *Proxy) UpdateMaxStake(valid, invalid string) { 13 | err := p.updateMaxStake(invalid,"5000000000") 14 | if err == nil { 15 | panic("update max stake with invalid key failed") 16 | } 17 | 18 | fmt.Println("update max stake with invalid key succeed") 19 | 20 | err2 := p.updateMaxStake(valid,"5000000000") 21 | if err2 != nil { 22 | panic("update max stake with valid key failed") 23 | } 24 | 25 | fmt.Println("update max stake with valid key succeed") 26 | 27 | } 28 | 29 | // stakeNum := "5000000000" 30 | func (p *Proxy) updateMaxStake(private string, stakeNum string) error { 31 | if err0 := p.unpause(private); err0 != nil { 32 | panic("unpause with valid account failed") 33 | } 34 | proxy, _ := bech32.ToBech32Address(p.Addr) 35 | parameters := []contract2.Value{ 36 | { 37 | VName: "max_stake", 38 | Type: "Uint128", 39 | Value: stakeNum, 40 | }, 41 | } 42 | args, _ := json.Marshal(parameters) 43 | if err2, output := ExecZli("contract", "call", 44 | "-k", private, 45 | "-a", proxy, 46 | "-t", "update_maxstake", 47 | "-f", "true", 48 | "-r", string(args)); err2 != nil { 49 | return errors.New("call transition error: " + err2.Error()) 50 | } else { 51 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 52 | fmt.Println("transaction id = ", tx) 53 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 54 | receipt := payload["receipt"].(map[string]interface{}) 55 | success := receipt["success"].(bool) 56 | if success { 57 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 58 | minstake := res["maxstake"].(string) 59 | if minstake == stakeNum { 60 | return nil 61 | } else { 62 | return errors.New("state failed") 63 | } 64 | 65 | } else { 66 | return errors.New("transaction failed") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /phase0/tests/transitions/deposit_funds.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strconv" 7 | 8 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 9 | ) 10 | 11 | func (p *Proxy) TransferFundsAndDrainBalance(pri, pri2, funds string) { 12 | fmt.Println("------------------------ start transfer funds and drain balance ------------------------") 13 | err := p.transferFunds(pri, funds) 14 | if err != nil { 15 | panic("test transfer funds failed") 16 | } else { 17 | fmt.Println("test transfer funds succeed") 18 | } 19 | 20 | err3 := p.drainContractBalance(pri2) 21 | if err3 == nil { 22 | panic("test drain balance invalid admin failed") 23 | } else { 24 | fmt.Println("test drain balance invalid admin succeed") 25 | } 26 | 27 | err2 := p.drainContractBalance(pri) 28 | if err2 != nil { 29 | panic("test drain balance failed") 30 | } else { 31 | fmt.Println("test drain balance succeed") 32 | } 33 | 34 | fmt.Println("------------------------ end transfer funds and drain balance ------------------------") 35 | 36 | } 37 | 38 | func (p *Proxy) transferFunds(pri, funds string) error { 39 | proxy, _ := bech32.ToBech32Address(p.Addr) 40 | m := p.Provider.GetBalance(p.ImplAddress).Result.(map[string]interface{}) 41 | r := m["balance"].(string) 42 | old, err := strconv.ParseInt(r, 10, 64) 43 | if err != nil { 44 | return errors.New("parse balance error: " + err.Error()) 45 | } 46 | 47 | if err2, _ := ExecZli("contract", "call", 48 | "-k", pri, 49 | "-a", proxy, 50 | "-t", "AddFunds", 51 | "-m", funds, 52 | "-f", "true", 53 | "-r", "[]"); err2 != nil { 54 | return errors.New("call transition error: " + err2.Error()) 55 | } else { 56 | m := p.Provider.GetBalance(p.ImplAddress).Result.(map[string]interface{}) 57 | r := m["balance"].(string) 58 | newbalance, err := strconv.ParseInt(r, 10, 64) 59 | if err != nil { 60 | return errors.New("parse balance error: " + err.Error()) 61 | } 62 | d := newbalance - old 63 | delta := strconv.FormatInt(d, 10) 64 | if delta != funds { 65 | return errors.New("check state failed") 66 | } else { 67 | return nil 68 | } 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /tests/transitions/add_ssn_after_upgrade.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) AddSSNAfterUpgrade() { 6 | t.LogStart("AddSSNAfterUpgrade") 7 | // deploy 8 | proxy, ssnlist := t.DeployAndUpgrade() 9 | 10 | 11 | // unpause 12 | proxy.Unpause() 13 | // set staking parameters 14 | min := "100000000000000" 15 | more_than_min := "110000000000000" 16 | ten_zil := "10000000000000" 17 | delegMin := "50000" 18 | proxy.UpdateStakingParameters(min,delegMin) 19 | ssnlist.LogContractStateJson() 20 | 21 | // add ssn1 with stake deposit more than min stake 22 | txn,err := proxy.AddSSNAfterUpgrade("0x"+addr1,more_than_min) 23 | if err != nil { 24 | t.LogError("AddSSNAfterUpgrade",err) 25 | } 26 | receipt := t.GetReceiptString(txn) 27 | log.Println(receipt) 28 | state := ssnlist.LogContractStateJson() 29 | t.AssertContain(state,"\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"argtypes\":[],\"arguments\":[{\"argtypes\":[],\"arguments\":[],\"constructor\":\"True\"},\"110000000000000\",\"0\",\"fakename\",\"fakeurl\",\"fakeapi\",\"0\",\"0\",\"0\",\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\"],\"constructor\":\"Ssn\"}") 30 | 31 | // add ssn2 with stake deposit less than min stake 32 | txn,err1 := proxy.AddSSNAfterUpgrade("0x"+addr2,ten_zil) 33 | if err1 != nil { 34 | t.LogError("AddSSNAfterUpgrade",err1) 35 | } 36 | receipt = t.GetReceiptString(txn) 37 | log.Println(receipt) 38 | state = ssnlist.LogContractStateJson() 39 | t.AssertContain(state,"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\":{\"argtypes\":[],\"arguments\":[{\"argtypes\":[],\"arguments\":[],\"constructor\":\"False\"},\"10000000000000\",\"0\",\"fakename\",\"fakeurl\",\"fakeapi\",\"0\",\"0\",\"0\",\"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\"],\"constructor\":\"Ssn\"}") 40 | 41 | // add ssn2 again 42 | txn,err2 := proxy.AddSSNAfterUpgrade("0x"+addr2,ten_zil) 43 | if err2 != nil { 44 | t.LogError("AddSSNAfterUpgrade",err2) 45 | } 46 | receipt = t.GetReceiptString(txn) 47 | log.Println(receipt) 48 | t.AssertContain(receipt,"_eventname\":\"SSN already exists") 49 | ssnlist.LogContractStateJson() 50 | 51 | t.LogEnd("AddSSNAfterUpgrade") 52 | 53 | 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Proxy-Admin/upgradeTo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * upgrade underlying staking contract 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; 12 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 13 | const NEW_STAKING_CONTRACT = '0x1234567890123456789012345678901234567890'; 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin upgrade ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'upgradeTo', 32 | [ 33 | { 34 | vname: 'newImplementation', 35 | type: 'ByStr20', 36 | value: `${NEW_STAKING_CONTRACT}` 37 | } 38 | ], 39 | { 40 | version: VERSION, 41 | amount: new BN(0), 42 | gasPrice: GAS_PRICE, 43 | gasLimit: Long.fromNumber(30000) 44 | }, 45 | 33, 46 | 1000, 47 | true 48 | ); 49 | console.log("transaction: %o", callTx.id); 50 | console.log(JSON.stringify(callTx.receipt, null, 4)); 51 | } catch (err) { 52 | console.log(err); 53 | } 54 | console.log("------------------------ end upgrade ------------------------\n"); 55 | } 56 | 57 | main(); -------------------------------------------------------------------------------- /phase0/tests/transitions/update_contract_max_stake.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "strings" 10 | ) 11 | 12 | func (p *Proxy) UpdateContractMaxStake(valid, invalid string) { 13 | err := p.updateContractMaxStake(invalid, "100000000000000000") 14 | if err == nil { 15 | panic("update contract max stake with invalid key failed") 16 | } 17 | 18 | fmt.Println("update contract max stake with invalid key succeed") 19 | 20 | err2 := p.updateContractMaxStake(valid, "100000000000000000") 21 | if err2 != nil { 22 | panic("update contract max stake with valid key failed") 23 | } 24 | 25 | fmt.Println("update contract max stake with valid key succeed") 26 | 27 | } 28 | 29 | // stakeNum := "100000000000000000" 30 | func (p *Proxy) updateContractMaxStake(private string, stakeNum string) error { 31 | if err0 := p.unpause(private); err0 != nil { 32 | panic("unpause with valid account failed") 33 | } 34 | proxy, _ := bech32.ToBech32Address(p.Addr) 35 | parameters := []contract2.Value{ 36 | { 37 | VName: "max_stake", 38 | Type: "Uint128", 39 | Value: stakeNum, 40 | }, 41 | } 42 | args, _ := json.Marshal(parameters) 43 | if err2, output := ExecZli("contract", "call", 44 | "-k", private, 45 | "-a", proxy, 46 | "-t", "update_contractmaxstake", 47 | "-f", "true", 48 | "-r", string(args)); err2 != nil { 49 | return errors.New("call transition error: " + err2.Error()) 50 | } else { 51 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 52 | fmt.Println("transaction id = ", tx) 53 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 54 | receipt := payload["receipt"].(map[string]interface{}) 55 | success := receipt["success"].(bool) 56 | if success { 57 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 58 | minstake := res["contractmaxstake"].(string) 59 | if minstake == stakeNum { 60 | return nil 61 | } else { 62 | return errors.New("state failed") 63 | } 64 | 65 | } else { 66 | return errors.New("transaction failed") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/remove_ssn.js: -------------------------------------------------------------------------------- 1 | /* 2 | * remove ssn 3 | * used by admin 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 13 | const STAKING_PROXY_ADDR = toBech32Address("0xDB5Dc7118765A84B6c6A582280fA37A1DD2d9f69"); // checksum proxy address 14 | const SSN_ADDR = "0xf6dad9e193fa2959a849b81caf9cb6ecde466771" // ssn address to be removed with '0x' 15 | 16 | const zilliqa = new Zilliqa(API); 17 | const MSG_VERSION = 1; 18 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 19 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 20 | 21 | 22 | async function main() { 23 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 24 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 25 | console.log("Your account address is: %o", `${address}`); 26 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 27 | 28 | console.log("------------------------ begin remove ssn ------------------------\n"); 29 | try { 30 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 31 | const callTx = await contract.call( 32 | 'remove_ssn', 33 | [ 34 | { 35 | vname: 'ssnaddr', 36 | type: 'ByStr20', 37 | value: SSN_ADDR 38 | } 39 | ], 40 | { 41 | version: VERSION, 42 | amount: new BN(0), 43 | gasPrice: GAS_PRICE, 44 | gasLimit: Long.fromNumber(10000) 45 | }, 46 | 33, 47 | 1000, 48 | true 49 | ); 50 | console.log("transaction: %o", callTx.id); 51 | console.log(JSON.stringify(callTx.receipt, null, 4)); 52 | 53 | } catch (err) { 54 | console.log(err); 55 | } 56 | console.log("------------------------ end remove ssn ------------------------\n"); 57 | } 58 | 59 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/update_admin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * update admin 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 13 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 14 | const NEW_ADMIN_ADDR = "0x381f4008505e940ad7681ec3468a719060caf796"; // new admin checksum address with 0x 15 | 16 | const zilliqa = new Zilliqa(API); 17 | const MSG_VERSION = 1; 18 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 19 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin update admin ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'update_admin', 32 | [ 33 | { 34 | vname: 'admin', 35 | type: 'ByStr20', 36 | value: `${NEW_ADMIN_ADDR}` 37 | } 38 | ], 39 | { 40 | version: VERSION, 41 | amount: new BN(0), 42 | gasPrice: GAS_PRICE, 43 | gasLimit: Long.fromNumber(10000) 44 | }, 45 | 33, 46 | 1000, 47 | true 48 | ); 49 | console.log("transaction: %o", callTx.id); 50 | console.log(JSON.stringify(callTx.receipt, null, 4)); 51 | 52 | } catch (err) { 53 | console.log(err); 54 | } 55 | console.log("------------------------ end update admin ------------------------\n"); 56 | } 57 | 58 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/update_verifier.js: -------------------------------------------------------------------------------- 1 | /* 2 | * update verifier 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | // change the following parameters 9 | const API = 'http://localhost:5555' 10 | const CHAIN_ID = 1; 11 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 12 | const STAKING_PROXY_ADDR = toBech32Address("0xDB5Dc7118765A84B6c6A582280fA37A1DD2d9f69"); // checksum proxy address 13 | const NEW_VERIFIER = '0x381f4008505e940ad7681ec3468a719060caf796'; // new verifier checksum address with '0x' 14 | 15 | const zilliqa = new Zilliqa(API); 16 | const MSG_VERSION = 1; 17 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 18 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 19 | 20 | 21 | async function main() { 22 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 23 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 24 | console.log("Your account address is: %o", `${address}`); 25 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 26 | 27 | console.log("------------------------ begin update verifier ------------------------\n"); 28 | try { 29 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 30 | const callTx = await contract.call( 31 | 'update_verifier', 32 | [ 33 | { 34 | vname: 'verif', 35 | type: 'ByStr20', 36 | value: `${NEW_VERIFIER}` 37 | } 38 | ], 39 | { 40 | version: VERSION, 41 | amount: new BN(0), 42 | gasPrice: GAS_PRICE, 43 | gasLimit: Long.fromNumber(10000) 44 | }, 45 | 33, 46 | 1000, 47 | true 48 | ); 49 | console.log("transaction: %o", callTx.id); 50 | console.log(JSON.stringify(callTx.receipt, null, 4)); 51 | 52 | } catch (err) { 53 | console.log(err); 54 | } 55 | console.log("------------------------ end update verifier ------------------------\n"); 56 | } 57 | 58 | main(); -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Proxy-Admin/changeProxyAdmin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * change proxy contract admin 3 | */ 4 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 5 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 6 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 7 | 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 13 | const STAKING_PROXY_ADDR = toBech32Address("0x26b628F7a15584e2c6578B8B6572ae226c25bA3D"); // checksum proxy address 14 | const NEW_ADMIN_ADDR = "0x381f4008505e940ad7681ec3468a719060caf796"; // new admin checksum address with 0x 15 | 16 | const zilliqa = new Zilliqa(API); 17 | const MSG_VERSION = 1; 18 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 19 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 20 | 21 | 22 | async function main() { 23 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 24 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 25 | console.log("Your account address is: %o", `${address}`); 26 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 27 | 28 | console.log("------------------------ start ChangeProxyAdmin ------------------------\n"); 29 | try { 30 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 31 | const callTx = await contract.call( 32 | 'changeProxyAdmin', 33 | [ 34 | { 35 | vname: "newAdmin", 36 | type: 'ByStr20', 37 | value: `${NEW_ADMIN_ADDR}` 38 | } 39 | ], 40 | { 41 | version: VERSION, 42 | amount: new BN(0), 43 | gasPrice: GAS_PRICE, 44 | gasLimit: Long.fromNumber(30000) 45 | }, 46 | 33, 47 | 1000, 48 | true 49 | ); 50 | console.log("transaction: %o", callTx.id); 51 | console.log(JSON.stringify(callTx.receipt, null, 4)); 52 | 53 | } catch (err) { 54 | console.log(err); 55 | } 56 | console.log("------------------------ end ChangeProxyAdmin ------------------------\n"); 57 | } 58 | 59 | main(); -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | ### 1. Ensure you have [zli](https://github.com/Zilliqa/zli) installed 2 | 3 | can use following command to test: 4 | 5 | ```shell script 6 | zli -h 7 | ``` 8 | 9 | ### 2. Init your wallet config 10 | 11 | #### 1) Init a new fresh one 12 | 13 | ```shell script 14 | zli wallet init 15 | ``` 16 | 17 | Check your wallet config: 18 | 19 | ```shell script 20 | zli wallet echo 21 | ``` 22 | 23 | Transfer some zils your account before making any transaction. 24 | 25 | #### 2) Init for an exist private key 26 | 27 | If you already have one with zils, then can use that private key to init your wallet config: 28 | 29 | ```shell script 30 | zli wallet init -p your_private_key 31 | ``` 32 | 33 | Above two commands will generate a file located at ~/.zilliqa, try to edit it directly if you want to change api url or chain 34 | id. 35 | 36 | All following commands will use the private key you generated above, if you want to override it, just use `-k another_private_key` 37 | 38 | like `zli contract deploy -c ../contracts/proxy.scilla -i proxy.json -k 38f3715e7ef9b5a5080171dca4cb37b05eaa7e3b0d9a9427a11e021e1029525d`. 39 | 40 | But we still need to make `~/.zilliqa` exist, because we need `api url` and `chain id`. 41 | 42 | ### 3. Deploy proxy contract 43 | 44 | Run `sh ./deploy_proxy.sh` 45 | 46 | Make sure `proxy.json` contain an correct `init_admin`, usually from your config wallet, can use `zli wallet echo` to get. 47 | No need to modify `init_implementation`, will `upgrade` later. Both transaction id and contract address will be print on 48 | standard output. 49 | 50 | #### 4. Deploy sshlist contract 51 | 52 | Run `sh ./deploy_sshlist.sh` 53 | 54 | Also need to make sure you put correct `init_admin` and `proxy_address`. 55 | 56 | #### 5. Upgrade proxy contract 57 | 58 | Run `zli contract call -a 0x09710e00256db2e3db4b44f597f17f3d97f06318 -t upgradeTo -r "[{\"vname\":\"newImplementation\",\"type\":\"ByStr20\",\"value\":\"0x1256e7c364d4f5b4b579541d1483f4be9ab5bc3d\"}]" -f true` 59 | 60 | or `sh ./upgradeTo.sh` 61 | 62 | This allow you to make your proxy point to actual sshlist contract. 63 | 64 | #### 6. Others 65 | 66 | After doing deploy and upgrade, you can run any others script to call transitions. Just keep in mind do not mess up 67 | 68 | contract address, always modify the scripts to your own contract address 69 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/SSN-Operators/withdraw_stake_amount.js: -------------------------------------------------------------------------------- 1 | /* 2 | * withdraw stake deposit 3 | * used by ssn only 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = '589417286a3213dceb37f8f89bd164c3505a4cec9200c61f7c6db13a30a71b45'; // ssn private key 13 | const STAKING_PROXY_ADDR = toBech32Address("0xDB5Dc7118765A84B6c6A582280fA37A1DD2d9f69"); // checksum proxy address 14 | const WITHDRAW_AMOUNT = units.toQa('20', units.Units.Zil); // stake amount to be withdrawn defined in Zil converted to Qa 15 | 16 | const zilliqa = new Zilliqa(API); 17 | const MSG_VERSION = 1; 18 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 19 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 20 | 21 | 22 | async function main() { 23 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 24 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 25 | console.log("Your account address is: %o", `${address}`); 26 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 27 | 28 | console.log("------------------------ begin withdraw stake amount ------------------------\n"); 29 | try { 30 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 31 | const callTx = await contract.call( 32 | 'withdraw_stake_amount', 33 | [ 34 | { 35 | vname: 'amount', 36 | type: 'Uint128', 37 | value: `${WITHDRAW_AMOUNT}` 38 | } 39 | ], 40 | { 41 | version: VERSION, 42 | amount: new BN(0), 43 | gasPrice: GAS_PRICE, 44 | gasLimit: Long.fromNumber(30000) 45 | }, 46 | 33, 47 | 1000, 48 | true 49 | ); 50 | console.log("transaction: %o", callTx.id); 51 | console.log(JSON.stringify(callTx.receipt, null, 4)); 52 | 53 | } catch (err) { 54 | console.log(err); 55 | } 56 | console.log("------------------------ end withdraw stake amount ------------------------\n"); 57 | } 58 | 59 | main(); -------------------------------------------------------------------------------- /phase0/tests/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Zilliqa/stake-test/transitions" 5 | "fmt" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | // 0. prepare two private keys, recommend to use your own, in case conflicts 12 | // we need the second private key, as we need to test non-admin permission or something similar 13 | fromTime := time.Now() 14 | args := os.Args[1:] 15 | if len(args) != 3 { 16 | panic("parameters error") 17 | } 18 | pri1 := args[0] 19 | pri2 := args[1] 20 | api := args[2] 21 | 22 | // 1. make sure zli is already installed 23 | if err, output := transitions.ExecZli("-h"); err != nil { 24 | fmt.Println(err.Error()) 25 | return 26 | } else { 27 | fmt.Println(output) 28 | } 29 | 30 | // setup default wallet (if there is no default one) 31 | if err, output := transitions.ExecZli("wallet", "init"); err != nil { 32 | // no need to panic here, only to make sure there is a wallet file 33 | // fmt.Println(err.Error()) 34 | } else { 35 | fmt.Println(output) 36 | } 37 | if err, output := transitions.ExecZli("wallet", "echo"); err != nil { 38 | fmt.Println(err.Error()) 39 | return 40 | } else { 41 | fmt.Println(output) 42 | } 43 | 44 | err, proxy, impl := transitions.DeployAndUpgrade(pri1) 45 | if err != nil { 46 | panic("got error = " + err.Error()) 47 | } 48 | fmt.Println("proxy = ", proxy) 49 | fmt.Println("impl = ", impl) 50 | 51 | p := transitions.NewProxy(api, proxy, impl) 52 | 53 | // test ChangeProxyAdmin 54 | p.ChangeProxyAdmin(pri1, pri2) 55 | 56 | // test UpdateAdmin 57 | p.UpdateAdmin(pri1, pri2) 58 | 59 | // test Pause 60 | p.PauseAndUnPause(pri1, pri2) 61 | 62 | // test UpdateVerifier 63 | p.UpdateVerifier(pri1, pri2) 64 | 65 | p.UpdateStakingParameter(pri1,pri2) 66 | 67 | // test deposit 68 | p.TransferFundsAndDrainBalance(pri1, pri2, "5000") 69 | 70 | // test AddSSN 71 | transitions.TestAddSSN(pri1, pri2, api) 72 | 73 | transitions.TestStakeDeposit(pri1, pri2, api) 74 | 75 | transitions.TestWithdrawStakeRewards(pri1, pri2, api) 76 | 77 | transitions.TestAssignStakeReward(pri1, pri2, api) 78 | 79 | transitions.TestWithdrawAmount(pri1, pri2, api) 80 | 81 | transitions.TestRemoveSSN(pri1,pri2,api) 82 | 83 | endTime := time.Now() 84 | interval := endTime.Sub(fromTime).Minutes() 85 | fmt.Printf("The whole test cost %f minutes, oh my!\n", interval) 86 | } 87 | -------------------------------------------------------------------------------- /tests/transitions/update_commission.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | ) 7 | 8 | func (t *Testing) UpdateComm() { 9 | t.LogStart("UpdateComm") 10 | proxy, ssnlist := t.DeployAndUpgrade() 11 | 12 | // unpause 13 | proxy.Unpause() 14 | 15 | min := "100000" 16 | delegMin := "50000" 17 | txn, err1 := proxy.UpdateStakingParameters(min,delegMin) 18 | if err1 != nil { 19 | t.LogError("UpdateComm failed", err1) 20 | } 21 | receipt, _ := json.Marshal(txn.Receipt) 22 | recp := string(receipt) 23 | log.Println(recp) 24 | 25 | // update verifier to ssn1 26 | proxy.UpdateVerifier("0x" + addr1) 27 | // update verifier receiving addr to addr1 28 | proxy.UpdateVerifierRewardAddr("0x" + addr1) 29 | 30 | // pause 31 | proxy.Pause() 32 | proxy.PopulateTotalStakeAmt("400000") 33 | // unpause 34 | proxy.Unpause() 35 | 36 | // add ssn1 37 | proxy.AddSSNAfterUpgrade("0x"+addr1, "200000") 38 | txn, err2 := proxy.UpdateStakingParameters(min,delegMin) 39 | if err2 != nil { 40 | t.LogError("UpdateComm failed", err2) 41 | } 42 | receipt, _ = json.Marshal(txn.Receipt) 43 | recp = string(receipt) 44 | ssnlist.LogContractStateJson() 45 | 46 | // ssn1 update commission within this cycle 47 | txn, err3 := proxy.UpdateComm("100000000") 48 | t.AssertError(err3) 49 | receipt, _ = json.Marshal(txn.Receipt) 50 | recp = string(receipt) 51 | log.Println(recp) 52 | t.AssertContain(recp, "Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -9))])") 53 | ssnlist.LogContractStateJson() 54 | 55 | // reward to increase cycle 56 | proxy.AssignStakeReward("0x"+addr1, "52000000") 57 | ssnlist.LogContractStateJson() 58 | 59 | // update commission with a legal number 60 | txn, err6 := proxy.UpdateComm("200000000") 61 | if err6 != nil { 62 | t.LogError("UpdateComm", err6) 63 | } 64 | 65 | // update commission again 66 | txn, err4 := proxy.UpdateComm("300000000") 67 | t.AssertError(err4) 68 | 69 | // as non ssn, update commission 70 | proxy.UpdateWallet(key2) 71 | txn, err5 := proxy.UpdateComm("150000000") 72 | t.AssertError(err5) 73 | receipt, _ = json.Marshal(txn.Receipt) 74 | recp = string(receipt) 75 | log.Println(recp) 76 | t.AssertContain(recp,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -10))])") 77 | ssnlist.LogContractStateJson() 78 | 79 | t.LogEnd("UpdateComm") 80 | } 81 | -------------------------------------------------------------------------------- /tests/deploy/ssnlist.go: -------------------------------------------------------------------------------- 1 | package deploy 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "log" 8 | 9 | "github.com/Zilliqa/gozilliqa-sdk/account" 10 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 11 | "github.com/Zilliqa/gozilliqa-sdk/core" 12 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 13 | provider2 "github.com/Zilliqa/gozilliqa-sdk/provider" 14 | "github.com/Zilliqa/gozilliqa-sdk/util" 15 | ) 16 | 17 | type SSNList struct { 18 | Code string 19 | Init []core.ContractValue 20 | Addr string 21 | } 22 | 23 | func (s *SSNList) LogContractStateJson() string { 24 | provider := provider2.NewProvider("https://zilliqa-isolated-server.zilliqa.com/") 25 | rsp, _ := provider.GetSmartContractState(s.Addr) 26 | j, _ := json.Marshal(rsp) 27 | s.LogPrettyStateJson(rsp) 28 | return string(j) 29 | } 30 | 31 | func (s *SSNList) LogPrettyStateJson(data interface{}) { 32 | j, _ := json.MarshalIndent(data, "", " ") 33 | log.Println(string(j)) 34 | } 35 | 36 | func (s *SSNList) GetBalance() string { 37 | provider := provider2.NewProvider("https://zilliqa-isolated-server.zilliqa.com/") 38 | balAndNonce, _ := provider.GetBalance(s.Addr) 39 | return balAndNonce.Balance 40 | } 41 | 42 | func NewSSNList(key string, proxy string) (*SSNList, error) { 43 | code, _ := ioutil.ReadFile("./ssnlist.scilla") 44 | adminAddr := keytools.GetAddressFromPrivateKey(util.DecodeHex(key)) 45 | 46 | init := []core.ContractValue{ 47 | { 48 | VName: "_scilla_version", 49 | Type: "Uint32", 50 | Value: "0", 51 | }, { 52 | VName: "init_admin", 53 | Type: "ByStr20", 54 | Value: "0x" + adminAddr, 55 | }, { 56 | VName: "init_proxy_address", 57 | Type: "ByStr20", 58 | Value: "0x" + proxy, 59 | }, 60 | { 61 | VName: "init_gzil_address", 62 | Type: "ByStr20", 63 | Value: "0x" + adminAddr, 64 | }, 65 | } 66 | 67 | wallet := account.NewWallet() 68 | wallet.AddByPrivateKey(key) 69 | 70 | contract := contract2.Contract{ 71 | Code: string(code), 72 | Init: init, 73 | Signer: wallet, 74 | } 75 | 76 | tx, err := contract.DeployTo("isolated", "50000") 77 | if err != nil { 78 | return nil, err 79 | } 80 | tx.Confirm(tx.ID, 1000, 10, contract.Provider) 81 | if tx.Status == core.Confirmed { 82 | return &SSNList{ 83 | Code: string(code), 84 | Init: init, 85 | Addr: tx.ContractAddress, 86 | }, nil 87 | } else { 88 | return nil, errors.New("deploy failed") 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /phase0/tests/transitions/update_verifier.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 10 | "github.com/Zilliqa/gozilliqa-sdk/util" 11 | "strings" 12 | ) 13 | 14 | func (p *Proxy) UpdateVerifier(valid, invalid string) { 15 | err := p.updateVerifier(valid) 16 | if err != nil { 17 | panic("update verifier with admin failed: " + err.Error()) 18 | } 19 | fmt.Println("update verifier with admin succeed") 20 | 21 | err2 := p.updateVerifier(invalid) 22 | if err2 == nil { 23 | panic("update verifier with invalid admin failed") 24 | } 25 | fmt.Println("update verifier with invalid admin succeed") 26 | } 27 | 28 | func (p *Proxy) updateVerifierTo(private string, newVerifier string) error { 29 | proxy, _ := bech32.ToBech32Address(p.Addr) 30 | 31 | parameters := []contract2.Value{ 32 | { 33 | VName: "verif", 34 | Type: "ByStr20", 35 | Value: newVerifier, 36 | }, 37 | } 38 | args, _ := json.Marshal(parameters) 39 | if err2, output := ExecZli("contract", "call", 40 | "-k", private, 41 | "-a", proxy, 42 | "-t", "update_verifier", 43 | "-f", "true", 44 | "-r", string(args)); err2 != nil { 45 | return errors.New("call transition error: " + err2.Error()) 46 | } else { 47 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 48 | fmt.Println("transaction id = ", tx) 49 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 50 | receipt := payload["receipt"].(map[string]interface{}) 51 | success := receipt["success"].(bool) 52 | if success { 53 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 54 | verifier := res["verifier"].(map[string]interface{}) 55 | arguments := verifier["arguments"].([]interface{})[0] 56 | fmt.Println(arguments) 57 | if arguments == nil { 58 | return errors.New("verifier is none") 59 | } 60 | arg := arguments.(string) 61 | if arg == newVerifier { 62 | return nil 63 | } else { 64 | return errors.New("update state failed") 65 | } 66 | } else { 67 | return errors.New("transaction failed") 68 | } 69 | } 70 | } 71 | 72 | func (p *Proxy) updateVerifier(private string) error { 73 | operator := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(private)) 74 | return p.updateVerifierTo(private, operator) 75 | } 76 | -------------------------------------------------------------------------------- /phase0/tests/transitions/update_admin.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 10 | "github.com/Zilliqa/gozilliqa-sdk/util" 11 | "strings" 12 | ) 13 | 14 | func (p *Proxy) UpdateAdmin(oldPrivateKey, newPrivateKey string) { 15 | fmt.Println("------------------------ begin update admin ------------------------") 16 | err := p.updateAdmin(oldPrivateKey, newPrivateKey) 17 | if err != nil { 18 | panic("update admin with admin permission failed" + err.Error()) 19 | } 20 | fmt.Println("update admin with admin permission succeed") 21 | err2 := p.updateAdmin(oldPrivateKey, newPrivateKey) 22 | if err2 == nil { 23 | panic("update admin without admin permission failed") 24 | } 25 | fmt.Println("update admin without admin permission succeed") 26 | err3 := p.updateAdmin(newPrivateKey, oldPrivateKey) 27 | if err3 != nil { 28 | panic("revert admin failed") 29 | } 30 | fmt.Println("revert admin succeed") 31 | fmt.Println("------------------------ end update admin ------------------------") 32 | } 33 | 34 | func (p *Proxy) updateAdmin(oldPrivateKey, newPrivateKey string) error { 35 | newAddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(newPrivateKey)) 36 | proxy, _ := bech32.ToBech32Address(p.Addr) 37 | parameters := []contract2.Value{ 38 | { 39 | VName: "admin", 40 | Type: "ByStr20", 41 | Value: newAddr, 42 | }, 43 | } 44 | 45 | args, _ := json.Marshal(parameters) 46 | if err2, output := ExecZli("contract", "call", 47 | "-k", oldPrivateKey, 48 | "-a", proxy, 49 | "-t", "update_admin", 50 | "-f","true", 51 | "-r", string(args)); err2 != nil { 52 | return errors.New("call transition error: " + err2.Error()) 53 | } else { 54 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 55 | fmt.Println("transaction id = ", tx) 56 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 57 | receipt := payload["receipt"].(map[string]interface{}) 58 | success := receipt["success"].(bool) 59 | if success { 60 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 61 | contractAdmin := res["contractadmin"].(string) 62 | if contractAdmin == newAddr { 63 | return nil 64 | } else { 65 | return errors.New("update state error") 66 | } 67 | } else { 68 | return errors.New("transaction failed") 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /phase0/scripts/Golang-ZLI/README.md: -------------------------------------------------------------------------------- 1 | ### Contents 2 | The scripts are divided into folders based on the following roles 3 | - Contract admin 4 | - Verifier 5 | - Staked seed node operator 6 | - Proxy contract admin 7 | 8 | 9 | ### 1. Ensure you have [zli](https://github.com/Zilliqa/zli) installed 10 | 11 | can use following command to test: 12 | 13 | ```shell script 14 | zli -h 15 | ``` 16 | 17 | ### 2. Init your wallet config 18 | 19 | #### 1) Init a new fresh one 20 | 21 | ```shell script 22 | zli wallet init 23 | ``` 24 | 25 | Check your wallet config: 26 | 27 | ```shell script 28 | zli wallet echo 29 | ``` 30 | 31 | Transfer some zils your account before making any transaction. 32 | 33 | #### 2) Init for an exist private key 34 | 35 | If you already have one with zils, then can use that private key to init your wallet config: 36 | 37 | ```shell script 38 | zli wallet from -p your_private_key 39 | ``` 40 | 41 | Above two commands will generate a file located at ~/.zilliqa, try to edit it directly if you want to change api url or chain 42 | id. 43 | 44 | All following commands will use the private key you generated above, if you want to override it, just use `-k another_private_key` 45 | 46 | like `zli contract deploy -c ../contracts/proxy.scilla -i proxy.json -k 38f3715e7ef9b5a5080171dca4cb37b05eaa7e3b0d9a9427a11e021e1029525d`. 47 | 48 | But we still need to make `~/.zilliqa` exist, because we need `api url` and `chain id`. 49 | 50 | ### 3. Deploy proxy contract 51 | 52 | Run `sh ./deploy_proxy.sh` 53 | 54 | Make sure `proxy.json` contain an correct `init_admin`, usually from your config wallet, can use `zli wallet echo` to get. 55 | No need to modify `init_implementation`, will `upgrade` later. Both transaction id and contract address will be print on 56 | standard output. 57 | 58 | #### 4. Deploy sshlist contract 59 | 60 | Run `sh ./deploy_sshlist.sh` 61 | 62 | Also need to make sure you put correct `init_admin` and `proxy_address`. 63 | 64 | #### 5. Upgrade proxy contract 65 | 66 | Run `zli contract call -a 0x09710e00256db2e3db4b44f597f17f3d97f06318 -t upgradeTo -r "[{\"vname\":\"newImplementation\",\"type\":\"ByStr20\",\"value\":\"0x1256e7c364d4f5b4b579541d1483f4be9ab5bc3d\"}]" -f true` 67 | 68 | or `sh ./upgradeTo.sh` 69 | 70 | This allow you to make your proxy point to actual sshlist contract. 71 | 72 | #### 6. Others 73 | 74 | After doing deploy and upgrade, you can run any others script to call transitions. Just keep in mind do not mess up 75 | 76 | contract address, always modify the scripts to your own contract address 77 | -------------------------------------------------------------------------------- /phase0/scripts/Java/README.md: -------------------------------------------------------------------------------- 1 | # Java sample code for SSN operators 2 | This repository contains some sample codes, illustrating how third parties or organizations integrate with Zilliqa staking contract as SSN operators. 3 | 4 | ## SSNOperator.java 5 | [SSNOperator.java](./src/main/java/com/zilliqa/staking/SSNOperator.java) cointains the sample codes for SSN operators to interact with the SSN smart contract. 6 | 7 | ### public String stakeDeposit(String amount, int attempts, int interval) 8 | This function allows the SSN operator to deposit stake amount into the SSN smart contract. 9 | ```java 10 | @param amount staking amount 11 | @param attempts attempt times for polling transaction 12 | @param interval interval time in seconds between each polling 13 | ``` 14 | 15 | ### public String withdrawStakeAmount(String amount, int attempts, int interval) 16 | This function allows the SSN operator to withdraw stake amount *(excluding reward)* from the SSN smart contract. 17 | ```java 18 | @param amount withdraw amount 19 | @param attempts attempt times for polling transaction 20 | @param interval interval time in seconds between each polling 21 | ``` 22 | 23 | ### public String withdrawStakeRewards(int attempts, int interval) 24 | This function allows the SSN operator to withdraw *all* the stake reward from the SSN smart contract. 25 | ```java 26 | @param attempts attempt times for polling transaction 27 | @param interval interval time in seconds between each polling 28 | ``` 29 | 30 | ### public String getStakeAmount() 31 | This function allows the SSN operator to get stake amount *(excluding reward)* from the SSN smart contract. 32 | 33 | ### public String getStakeBufferedAmount() 34 | This function allows the SSN operator to get buffered stake amount from the SSN smart contract. 35 | 36 | ### public String getStakeRewards() 37 | This function allows the SSN operator to get stake reward amount from the SSN smart contract. 38 | 39 | ### public Boolean getActiveStatus() 40 | This function allows the SSN operator to get the current status (active/inactive) of the SSN. An inactive SSN is usually a result of the existing stake amount less than minstake. 41 | 42 | ### public Boolean getNodeStatus(String publicApi, int tolerance) 43 | This function allows the SSN operator to check whether is the node is in-sync with the network, up to a certain tolerance. 44 | ```java 45 | @param publicApi public api endpoint maintained by Zilliqa, typically https://dev-api.zilliqa.com for community testnet and https://api.zilliqa.com for mainnet 46 | @param tolerance tolerance of the gap of the tx block number 47 | ``` 48 | -------------------------------------------------------------------------------- /tests/transitions/delegate_stake.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) DelegateStake() { 6 | t.LogStart("DelegateStake") 7 | 8 | // deploy smart contract 9 | proxy, ssnlist := t.DeployAndUpgrade() 10 | ssnlist.LogContractStateJson() 11 | // unpause 12 | proxy.Unpause() 13 | 14 | // set staking parameters 15 | min := "100000000000000" 16 | delegMin := "50000" 17 | proxy.UpdateStakingParameters(min,delegMin) 18 | 19 | // add ssn 20 | proxy.AddSSN("0x"+addr2,"xiaohuo") 21 | ssnlist.LogContractStateJson() 22 | 23 | // use add1 to deposit less than delegMin 24 | txn,err0 := proxy.DelegateStake("0x"+addr2,"10") 25 | t.AssertError(err0) 26 | t.LogPrettyReceipt(txn) 27 | receipt := t.GetReceiptString(txn) 28 | t.AssertContain(receipt,"Int32 -15") 29 | 30 | 31 | // use addr1 to deposit (should enter direct deposit map) 32 | // ssn becomes active 33 | txn,err := proxy.DelegateStake("0x"+addr2,"100000000000000") 34 | if err != nil { 35 | t.LogError("DelegateStake",err) 36 | } 37 | receipt = t.GetReceiptString(txn) 38 | log.Println(receipt) 39 | state := ssnlist.LogContractStateJson() 40 | t.AssertContain(state,"_balance\":\"100000000000000") 41 | t.AssertContain(state,"deposit_amt_deleg\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\":\"100000000000000\"}") 42 | t.AssertContain(state,"direct_deposit_deleg\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\":{\"1\":\"100000000000000\"}}") 43 | 44 | // use addr1 to deposit again (should enter buffer deposit map) 45 | txn,err2 := proxy.DelegateStake("0x"+addr2,"100000000000000") 46 | if err2 != nil { 47 | t.LogError("DelegateStake",err2) 48 | } 49 | receipt = t.GetReceiptString(txn) 50 | log.Println(receipt) 51 | state = ssnlist.LogContractStateJson() 52 | t.AssertContain(state,"_balance\":\"200000000000000") 53 | t.AssertContain(state,"direct_deposit_deleg\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\":{\"1\":\"100000000000000\"}}") 54 | t.AssertContain(state,"buff_deposit_deleg\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"0xe2cd74983c7a3487af3a133a3bf4e7dd76f5d928\":{\"1\":\"100000000000000\"}}") 55 | t.LogEnd("DelegateStake") 56 | 57 | // delegate to a non-existent ssn, should raise exception 58 | txn,err3 := proxy.DelegateStake("0x"+addr1,"100000000000000") 59 | t.AssertError(err3) 60 | receipt = t.GetReceiptString(txn) 61 | log.Println(receipt) 62 | state = ssnlist.LogContractStateJson() 63 | t.LogEnd("DelegateStake") 64 | } 65 | -------------------------------------------------------------------------------- /phase0/tests/transitions/update_staking_parameter.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "strings" 10 | ) 11 | 12 | func (p *Proxy) UpdateStakingParameter(valid, invalid string) { 13 | err := p.updateStakingParameter(invalid, "1000000000", "5000000000", "100000000000000000") 14 | if err == nil { 15 | panic("update staking parameter with invalid key failed") 16 | } 17 | 18 | fmt.Println("update min stake with invalid key succeed") 19 | 20 | err2 := p.updateStakingParameter(valid, "1000000000", "5000000000", "100000000000000000") 21 | if err2 != nil { 22 | panic("update min stake with valid key failed: " + err2.Error()) 23 | } 24 | 25 | fmt.Println("update min stake with valid key succeed") 26 | 27 | } 28 | 29 | func (p *Proxy) updateStakingParameter(private string, minStake, maxStake, contractMaxStake string) error { 30 | if err0 := p.unpause(private); err0 != nil { 31 | panic("unpause with valid account failed") 32 | } 33 | 34 | proxy, _ := bech32.ToBech32Address(p.Addr) 35 | parameters := []contract2.Value{ 36 | { 37 | VName: "min_stake", 38 | Type: "Uint128", 39 | Value: minStake, 40 | }, 41 | { 42 | VName: "max_stake", 43 | Type: "Uint128", 44 | Value: maxStake, 45 | }, 46 | { 47 | VName: "contract_max_stake", 48 | Type: "Uint128", 49 | Value: contractMaxStake, 50 | }, 51 | } 52 | args, _ := json.Marshal(parameters) 53 | if err2, output := ExecZli("contract", "call", 54 | "-k", private, 55 | "-a", proxy, 56 | "-t", "update_staking_parameter", 57 | "-f", "true", 58 | "-r", string(args)); err2 != nil { 59 | return errors.New("call transition error: " + err2.Error()) 60 | } else { 61 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 62 | fmt.Println("transaction id = ", tx) 63 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 64 | receipt := payload["receipt"].(map[string]interface{}) 65 | success := receipt["success"].(bool) 66 | if success { 67 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 68 | minstake := res["minstake"].(string) 69 | maxstake := res["maxstake"].(string) 70 | contractmaxstake := res["contractmaxstake"].(string) 71 | if minstake == minstake && maxstake == maxStake && contractmaxstake == contractMaxStake { 72 | return nil 73 | } else { 74 | return errors.New("state failed") 75 | } 76 | } else { 77 | return errors.New("transaction failed") 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/add_ssn.js: -------------------------------------------------------------------------------- 1 | /* 2 | * add ssn 3 | * used by admin only 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const URL_API = API; 12 | const URL_RAW = API; 13 | const CHAIN_ID = 1; 14 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 15 | const STAKING_PROXY_ADDR = toBech32Address("0x35C36cEC66a7f5f5393f8b84eB56F4bd552dDb87"); // checksum proxy address 16 | const SSN_ADDR = "0xf6dad9e193fa2959a849b81caf9cb6ecde466771" // ssn address to be registered with '0x' 17 | 18 | const zilliqa = new Zilliqa(API); 19 | const MSG_VERSION = 1; 20 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 21 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 22 | 23 | async function main() { 24 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 25 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 26 | console.log("Your account address is: %o", `${address}`); 27 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 28 | 29 | console.log("------------------------ begin add ssn ------------------------\n"); 30 | try { 31 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 32 | const callTx = await contract.call( 33 | 'add_ssn', 34 | [ 35 | { 36 | vname: 'ssnaddr', 37 | type: 'ByStr20', 38 | value: `${SSN_ADDR}` 39 | }, 40 | { 41 | vname: 'urlraw', 42 | type: 'String', 43 | value: `${URL_RAW}` 44 | }, 45 | { 46 | vname: 'urlapi', 47 | type: 'String', 48 | value: `${URL_API}` 49 | } 50 | ], 51 | { 52 | version: VERSION, 53 | amount: new BN(0), 54 | gasPrice: GAS_PRICE, 55 | gasLimit: Long.fromNumber(10000) 56 | }, 57 | 33, 58 | 1000, 59 | true 60 | ); 61 | console.log("transaction: %o", callTx.id); 62 | console.log(JSON.stringify(callTx.receipt, null, 4)); 63 | console.log("------------------------ end add ssn ------------------------\n"); 64 | 65 | } catch (err) { 66 | console.log(err); 67 | } 68 | } 69 | 70 | main(); -------------------------------------------------------------------------------- /tests/transitions/add_delegator.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import "log" 4 | 5 | func (t *Testing) AddDelegator() { 6 | 7 | t.LogStart("AddDelegator") 8 | 9 | proxy, ssnlist := t.DeployAndUpgrade() 10 | 11 | // add ssn1,ssn2 12 | ssnlist.LogContractStateJson() 13 | proxy.AddSSN("0x"+addr1, "ssn1") 14 | proxy.AddSSN("0x"+addr2, "ssn2") 15 | ssnlist.LogContractStateJson() 16 | 17 | proxy.AddFunds("1000000") 18 | 19 | // as admin, update delegator (addr1) with 100000 to ssn1 (addr1) 20 | tnx, err := proxy.AddDelegator("0x"+addr1, "0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82", "100000") 21 | if err != nil { 22 | t.LogError("AddDelegator", err) 23 | } 24 | receipt := t.GetReceiptString(tnx) 25 | log.Println(receipt) 26 | state := ssnlist.LogContractStateJson() 27 | t.AssertContain(state,"\"deposit_amt_deleg\":{\"0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":\"100000\"}") 28 | 29 | // as admin, update delegator (addr1) with 200000 to ssn1 (add1) 30 | tnx, err1 := proxy.AddDelegator("0x"+addr1, "0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82", "200000") 31 | if err1 != nil { 32 | t.LogError("AddDelegator", err1) 33 | } 34 | receipt = t.GetReceiptString(tnx) 35 | log.Println(receipt) 36 | state = ssnlist.LogContractStateJson() 37 | t.AssertContain(state,"\"deposit_amt_deleg\":{\"0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":\"300000\"}") 38 | 39 | // as admin, update delegator (addr1) with 0 to ssn1 (add1) 40 | tnx, err2 := proxy.AddDelegator("0x"+addr1, "0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82", "0") 41 | if err2 != nil { 42 | t.LogError("AddDelegator", err2) 43 | } 44 | receipt = t.GetReceiptString(tnx) 45 | log.Println(receipt) 46 | t.AssertContain(receipt,"Deleg deleted") 47 | state = ssnlist.LogContractStateJson() 48 | 49 | // as admin, update delegator (addr2) with 100000 to ssn2 (addr2) 50 | tnx, err3 := proxy.AddDelegator("0x"+addr2, "0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed81", "100000") 51 | if err3 != nil { 52 | t.LogError("AddDelegator", err3) 53 | } 54 | receipt = t.GetReceiptString(tnx) 55 | t.AssertContain(receipt,"Deleg added") 56 | log.Println(receipt) 57 | state = ssnlist.LogContractStateJson() 58 | 59 | // as non admin, add delegator 60 | proxy.UpdateWallet(key2) 61 | tnx, err4 := proxy.AddDelegator("0x"+addr1, "0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed83", "100000") 62 | t.AssertError(err4) 63 | receipt = t.GetReceiptString(tnx) 64 | log.Println(receipt) 65 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -3))])") 66 | state = ssnlist.LogContractStateJson() 67 | t.LogEnd("AddDelegator") 68 | 69 | } 70 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/verifier/assign_stake_reward.js: -------------------------------------------------------------------------------- 1 | /* 2 | * assign stake reward 3 | * used by verifier only 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'd96e9eb5b782a80ea153c937fa83e5948485fbfc8b7e7c069d7b914dbc350aba'; // verifier 13 | const STAKING_PROXY_ADDR = toBech32Address("0xDB5Dc7118765A84B6c6A582280fA37A1DD2d9f69"); // checksum proxy address 14 | const REWARD_BLOCKNUM = 50000; // tx block num when ssns were verified 15 | // in the arguments, the second parameter '50' is the percentage of stake_deposit to reward 16 | const SSN_REWARD_LIST = [ 17 | { 18 | "constructor": "SsnRewardShare", 19 | "argtypes": "[]", 20 | "arguments": [ 21 | "0xf6dad9e193fa2959a849b81caf9cb6ecde466771", 22 | "50" 23 | ] 24 | } 25 | ]; 26 | 27 | const zilliqa = new Zilliqa(API); 28 | const MSG_VERSION = 1; 29 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 30 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 31 | 32 | 33 | async function main() { 34 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 35 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 36 | console.log("Your account address is: %o", `${address}`); 37 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 38 | 39 | console.log("------------------------ begin assign stake reward ------------------------\n"); 40 | try { 41 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 42 | const callTx = await contract.call( 43 | 'assign_stake_reward', 44 | [ 45 | { 46 | vname: 'ssnreward_list', 47 | type: 'List SsnRewardShare', 48 | value: SSN_REWARD_LIST 49 | }, 50 | { 51 | vname: 'reward_blocknum', 52 | type: 'Uint32', 53 | value: `${REWARD_BLOCKNUM}` 54 | }, 55 | ], 56 | { 57 | version: VERSION, 58 | amount: new BN(0), 59 | gasPrice: GAS_PRICE, 60 | gasLimit: Long.fromNumber(10000) 61 | }, 62 | 33, 63 | 1000, 64 | true 65 | ); 66 | console.log("transaction: %o", callTx.id); 67 | console.log(JSON.stringify(callTx.receipt, null, 4)); 68 | 69 | } catch (err) { 70 | console.log(err); 71 | } 72 | console.log("------------------------ end assign stake reward ------------------------\n"); 73 | } 74 | 75 | main(); -------------------------------------------------------------------------------- /phase0/tests/transitions/pause_and_unpause.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 7 | ) 8 | 9 | func (p *Proxy) PauseAndUnPause(valid, invalid string) { 10 | fmt.Println("------------------------ begin pause unpause ------------------------") 11 | if err1 := p.unpause(valid); err1 != nil { 12 | panic("unpause with valid account failed") 13 | } 14 | if err2 := p.pause(invalid); err2 == nil { 15 | panic("pause with invalid account failed") 16 | } else { 17 | if err2.Error() == "failed" { 18 | fmt.Println("pause with invalid account succeed") 19 | } else { 20 | panic("pause with invalid account failed: " + err2.Error()) 21 | } 22 | } 23 | 24 | err := p.pause(valid) 25 | if err != nil { 26 | panic("pause with valid account failed: " + err.Error()) 27 | } 28 | fmt.Println("pause with valid account succeed") 29 | 30 | if err3 := p.unpause(invalid); err3 == nil { 31 | panic("unpause with invalid account failed") 32 | } else { 33 | if err3.Error() == "failed" { 34 | fmt.Println("unpause with invalid account succeed") 35 | } else { 36 | panic("unpause with invalid account failed: " + err3.Error()) 37 | } 38 | } 39 | err4 := p.unpause(valid) 40 | if err4 != nil { 41 | panic("unpause with valid account failed: " + err4.Error()) 42 | } 43 | fmt.Println("unpause with valid account succeed") 44 | fmt.Println("------------------------ end pause unpause ------------------------") 45 | 46 | } 47 | 48 | func (p *Proxy) pause(private string) error { 49 | proxy, _ := bech32.ToBech32Address(p.Addr) 50 | 51 | if err2, _ := ExecZli("contract", "call", 52 | "-k", private, 53 | "-a", proxy, 54 | "-t", "pause", 55 | "-f","true", 56 | "-r", "[]"); err2 != nil { 57 | return errors.New("call transition error: " + err2.Error()) 58 | } else { 59 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 60 | paused := res["paused"].(map[string]interface{}) 61 | constructor := paused["constructor"].(string) 62 | if constructor == "True" { 63 | return nil 64 | } else { 65 | return errors.New("failed") 66 | } 67 | } 68 | } 69 | 70 | func (p *Proxy) unpause(private string) error { 71 | proxy, _ := bech32.ToBech32Address(p.Addr) 72 | 73 | if err2, _ := ExecZli("contract", "call", 74 | "-k", private, 75 | "-a", proxy, 76 | "-t", "unpause", 77 | "-f","true", 78 | "-r", "[]"); err2 != nil { 79 | return errors.New("call transition error: " + err2.Error()) 80 | } else { 81 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 82 | paused := res["paused"].(map[string]interface{}) 83 | constructor := paused["constructor"].(string) 84 | if constructor == "False" { 85 | return nil 86 | } else { 87 | return errors.New("failed") 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Contract-Admin/update_staking_parameter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * update contract max stake 3 | * used by admin only 4 | */ 5 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 6 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 7 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 8 | 9 | // change the following parameters 10 | const API = 'http://localhost:5555' 11 | const CHAIN_ID = 1; 12 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; // admin 13 | const STAKING_PROXY_ADDR = toBech32Address("0x651b97542A0B339052d61eB13f6c4FcDBA1a0172"); // checksum proxy address 14 | const CONTRACT_MAX_STAKE = units.toQa('4000', units.Units.Zil); // contract max stake amount in ZIL converted to Qa 15 | const MAX_STAKE = units.toQa('3000', units.Units.Zil); // max stake amount in ZIL converted to Qa 16 | const MIN_STAKE = units.toQa('10', units.Units.Zil); // min stake amount in ZIL converted to Qa 17 | 18 | const zilliqa = new Zilliqa(API); 19 | const MSG_VERSION = 1; 20 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 21 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 22 | 23 | 24 | async function main() { 25 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 26 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 27 | console.log("Your account address is: %o", `${address}`); 28 | console.log("proxy: %o\n", STAKING_PROXY_ADDR); 29 | 30 | console.log("------------------------ begin update staking parameter ------------------------\n"); 31 | try { 32 | const contract = zilliqa.contracts.at(STAKING_PROXY_ADDR); 33 | const callTx = await contract.call( 34 | 'update_staking_parameter', 35 | [ 36 | { 37 | vname: 'min_stake', 38 | type: 'Uint128', 39 | value: `${MIN_STAKE}` 40 | }, 41 | { 42 | vname: 'max_stake', 43 | type: 'Uint128', 44 | value: `${MAX_STAKE}` 45 | }, 46 | { 47 | vname: 'contract_max_stake', 48 | type: 'Uint128', 49 | value: `${CONTRACT_MAX_STAKE}` 50 | } 51 | ], 52 | { 53 | version: VERSION, 54 | amount: new BN(0), 55 | gasPrice: GAS_PRICE, 56 | gasLimit: Long.fromNumber(10000) 57 | }, 58 | 33, 59 | 1000, 60 | true 61 | ); 62 | console.log("transaction: %o", callTx.id); 63 | console.log(JSON.stringify(callTx.receipt, null, 4)); 64 | 65 | } catch (err) { 66 | console.log(err); 67 | } 68 | console.log("------------------------ end update staking parameter ------------------------\n"); 69 | } 70 | 71 | main(); -------------------------------------------------------------------------------- /phase0/tests/transitions/change_proxy_admin.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 10 | "github.com/Zilliqa/gozilliqa-sdk/util" 11 | "strings" 12 | ) 13 | 14 | func (p *Proxy) ChangeProxyAdmin(oldPrivateKey, newPrivateKey string) { 15 | // change admin to fnewPrivateKey 16 | fmt.Println("------------------------ start ChangeProxyAdmin ------------------------") 17 | // test one have admin permission 18 | err2 := p.changeProxyAdmin(oldPrivateKey, newPrivateKey) 19 | if err2 != nil { 20 | panic("ChangeProxyAdmin failed: " + err2.Error()) 21 | } else { 22 | fmt.Println("ChangeProxyAdmin test one have admin permission succeed") 23 | } 24 | 25 | // test one does not have admin permission 26 | err3 := p.changeProxyAdmin(oldPrivateKey, newPrivateKey) 27 | 28 | if err3 == nil { 29 | panic("ChangeProxyAdmin failed: ") 30 | } else { 31 | fmt.Println("ChangeProxyAdmin test one does not have admin permission succeed") 32 | } 33 | 34 | // revert admin permission 35 | err4 := p.changeProxyAdmin(newPrivateKey, oldPrivateKey) 36 | if err4 != nil { 37 | panic("ChangeProxyAdmin failed: " + err4.Error()) 38 | } else { 39 | fmt.Println("ChangeProxyAdmin revert admin account succeed") 40 | } 41 | fmt.Println("------------------------ end ChangeProxyAdmin ------------------------") 42 | 43 | } 44 | 45 | func (p *Proxy) changeProxyAdmin(oldPrivateKey, newPrivateKey string) error { 46 | newAddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(newPrivateKey)) 47 | proxy, _ := bech32.ToBech32Address(p.Addr) 48 | parameters := []contract2.Value{ 49 | { 50 | VName: "newAdmin", 51 | Type: "ByStr20", 52 | Value: newAddr, 53 | }, 54 | } 55 | args, _ := json.Marshal(parameters) 56 | if err2, output := ExecZli("contract", "call", 57 | "-k", oldPrivateKey, 58 | "-a", proxy, 59 | "-t", "changeProxyAdmin", 60 | "-f","true", 61 | "-r", string(args)); err2 != nil { 62 | return err2 63 | } else { 64 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 65 | fmt.Println("transaction id = ", tx) 66 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 67 | receipt := payload["receipt"].(map[string]interface{}) 68 | success := receipt["success"].(bool) 69 | events := receipt["event_logs"] 70 | if success { 71 | event := p.extraEventName(events.([]interface{})) 72 | if event == "changeAdmin FailedNotAdmin" { 73 | return errors.New("ChangeProxyAdmin failed") 74 | } 75 | res := p.Provider.GetSmartContractState(p.Addr).Result.(map[string]interface{}) 76 | admin := res["admin"].(string) 77 | if newAddr == admin { 78 | return nil 79 | } else { 80 | return errors.New("ChangeProxyAdmin failed, state not equal") 81 | } 82 | 83 | } else { 84 | return errors.New("transaction failed") 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/transitions/withdraw_stake_amount.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | func (t *Testing) WithDrawStakeAmount() { 4 | t.LogStart("WithDrawStakeAmount") 5 | // deploy 6 | proxy, ssnlist := t.DeployAndUpgrade() 7 | 8 | // unpause 9 | proxy.Unpause() 10 | // set staking parameters 11 | min := "100000000000000" 12 | tenzil := "10000000000000" 13 | ssn1 := "0x"+addr1 14 | ssn2 := "0x"+addr2 15 | delegMin := "50000" 16 | proxy.UpdateStakingParameters(min,delegMin) 17 | // update verifier to addr1 18 | proxy.UpdateVerifier(ssn1) 19 | // add ssn1 20 | proxy.AddSSN(ssn1, "ssn1") 21 | proxy.AddSSN(ssn2, "ssn2") 22 | // add delegator (addr1) to ssn1 (addr1) with 10 zil 23 | proxy.UpdateWallet(key1) 24 | proxy.DelegateStake(ssn1,tenzil) 25 | // add delegator (addr2) to ssn1 (addr1) with 10 zil 26 | proxy.UpdateWallet(key2) 27 | proxy.DelegateStake(ssn1,tenzil) 28 | // add delegator (addr3) to ssn1 (addr1) with min zil 29 | proxy.UpdateWallet(key3) 30 | proxy.DelegateStake(ssn1,min) 31 | // ssn1 becomes active now 32 | ssnlist.LogContractStateJson() 33 | // fund min zil 34 | proxy.AddFunds(min) 35 | 36 | // delegator (addr2) delegate 10 zil, and it should enter in buffered deposit 37 | proxy.UpdateWallet(key2) 38 | proxy.DelegateStake("0x"+addr1, tenzil) 39 | ssnlist.LogContractStateJson() 40 | 41 | // non delegator(addr4) try to withdraw stake, should fail 42 | proxy.UpdateWallet(key4) 43 | txn, err := proxy.WithdrawStakeAmt("0x" + addr1,tenzil) 44 | t.AssertError(err) 45 | receipt := t.GetReceiptString(txn) 46 | t.LogPrettyReceipt(txn) 47 | t.AssertContain(receipt,"Exception thrown: (Message [(_exception : (String \\\"Error\\\")) ; (code : (Int32 -7))])") 48 | ssnlist.LogContractStateJson() 49 | 50 | // delegator (addr1) withdraw from ssn1 (addr1), remain active 51 | proxy.UpdateWallet(key1) 52 | txn, err1 := proxy.WithdrawStakeAmt("0x" + addr1,tenzil) 53 | if err1 != nil { 54 | t.LogError("WithDrawStakeAmount",err1) 55 | } 56 | receipt = t.GetReceiptString(txn) 57 | t.LogPrettyReceipt(txn) 58 | t.AssertContain(receipt,"Deleg withdraw deposit") 59 | ssnlist.LogContractStateJson() 60 | 61 | // delegator (addr2) withdraw from ssn2 (addr2), should fail 62 | proxy.UpdateWallet(key2) 63 | txn, err2 := proxy.WithdrawStakeAmt("0x" + addr2,tenzil) 64 | t.AssertError(err2) 65 | receipt = t.GetReceiptString(txn) 66 | t.LogPrettyReceipt(txn) 67 | t.AssertContain(receipt,"\"message\":\"Exception thrown: (Message [(_exception : (String \\\"Error\\\")") 68 | ssnlist.LogContractStateJson() 69 | 70 | // delegator (addr3) withdraw from ssn1 (addr1), should success, and ssn become inactive 71 | proxy.UpdateWallet(key3) 72 | txn, err3 := proxy.WithdrawStakeAmt("0x" + addr1,min) 73 | if err3 != nil { 74 | t.LogError("WithDrawStakeAmount",err3) 75 | } 76 | receipt = t.GetReceiptString(txn) 77 | t.LogPrettyReceipt(txn) 78 | state := ssnlist.LogContractStateJson() 79 | t.AssertContain(state,"\"ssnlist\":{\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\":{\"argtypes\":[],\"arguments\":[{\"argtypes\":[],\"arguments\":[],\"constructor\":\"False\"},\"10000000000000\",\"0\",\"ssn1\",\"fakeurl\",\"fakeapi\",\"10000000000000\",\"0\",\"0\",\"0x29cf16563fac1ad1596dfe6f333978fece9706ec\"],\"constructor\":\"Ssn\"}") 80 | 81 | t.LogEnd("WithDrawStakeAmount") 82 | } 83 | -------------------------------------------------------------------------------- /phase0/tests/README.md: -------------------------------------------------------------------------------- 1 | ## Testing using Zilliqa Isolated Server 2 | The Zilliqa isolated server is a simulated environment for smart contract testing. It uses the `accountstore` and scilla interpreter to run smart contract transactions in the absense of consensus protocol. This enables more rapid testing for smart contracts. 3 | 4 | Zilliqa hosts a public endpoint for Zilliqa Isolated Server over at `https://zilliqa-isolated-server.zilliqa.com` 5 | 6 | ### Requirements 7 | 8 | Golang (minimum version: go.1.12): 9 | * [Download page](https://golang.org/dl/) 10 | * [Installation instructions](https://golang.org/doc/install) 11 | 12 | Zilliqa command tool [zli](https://github.com/Zilliqa/zli) 13 | 14 | ### Generation of keypairs for unit tests 15 | 16 | some of the tests will require a large amount of ZILs. If you wish to run the test, you can either 17 | 1. Generate your own keypairs (2 keypairs) and requests a large amount of test ZILs from us 18 | 2. Get two pair of keypairs with test ZILs pre-loaded from us 19 | 20 | For the rest of this document, we will name the the private key of the keypairs as `pri1` and `pri2`. 21 | 22 | ### Setup zli command tool 23 | 24 | #### 1. Init wallet configuration with specific private key 25 | 26 | Run the following command to init your wallet with the provided private key: 27 | 28 | ```shell script 29 | zli wallet from -p `pri1` 30 | ``` 31 | 32 | A `.zilliqa` file containing the wallet configuration will be generated under your `USERS` directory after running this. You can checkout this either by using `cat ~/.zilliqa` or `zli wallet echo`, you will see something like the following: 33 | 34 | ```json 35 | {"api":"https://dev-api.zilliqa.com/","chain_id":333,"default_account":{"private_key":"e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020ccc","public_key":"036695e20c8339bd3aab70aead5fc0e35ade557b4d00f0552c62afa220ad0ee149","address":"ad7d96b8b4d7a13b96b0dd1081832606090c096d","bech_32_address":"zil1447edw9567snh94sm5ggrqexqcyscztddt2t94"},"accounts":[{"private_key":"e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020ccc","public_key":"036695e20c8339bd3aab70aead5fc0e35ade557b4d00f0552c62afa220ad0ee149","address":"ad7d96b8b4d7a13b96b0dd1081832606090c096d","bech_32_address":"zil1447edw9567snh94sm5ggrqexqcyscztddt2t94"}]} 36 | ``` 37 | 38 | 39 | #### 2. Modify `api` and `chain_id` 40 | 41 | Since we are using the `isolated server` rather than `community devnet`, we need to rewrite the parameters `api` and `chain_id` in `.zilliqa`: 42 | 43 | "api": "https://zilliqa-isolated-server.zilliqa.com/", 44 | "chain_id": 1, 45 | 46 | The changed file should looked similar to the following: 47 | 48 | ```json 49 | {"api":"https://zilliqa-isolated-server.zilliqa.com/","chain_id":1,"default_account":{"private_key":"e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020ccc","public_key":"036695e20c8339bd3aab70aead5fc0e35ade557b4d00f0552c62afa220ad0ee149","address":"ad7d96b8b4d7a13b96b0dd1081832606090c096d","bech_32_address":"zil1447edw9567snh94sm5ggrqexqcyscztddt2t94"},"accounts":[{"private_key":"e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020ccc","public_key":"036695e20c8339bd3aab70aead5fc0e35ade557b4d00f0552c62afa220ad0ee149","address":"ad7d96b8b4d7a13b96b0dd1081832606090c096d","bech_32_address":"zil1447edw9567snh94sm5ggrqexqcyscztddt2t94"}]} 50 | ``` 51 | 52 | ### Run tests 53 | 54 | With `zli` installed and configured, we can use `go run ` to run tests, for instance: 55 | 56 | ```go 57 | go run main/main.go e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020ccc 21d1af225dab7b791d656f2fba2f8b5ca513327f9dce29473a7ec2aba5351318 https://zilliqa-isolated-server.zilliqa.com/ 58 | ``` 59 | -------------------------------------------------------------------------------- /phase0/tests/transitions/deploy_and_upgrade.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 7 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 8 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 9 | "github.com/Zilliqa/gozilliqa-sdk/util" 10 | "io/ioutil" 11 | "os" 12 | "strings" 13 | ) 14 | 15 | // return proxy address and impl address 16 | func DeployAndUpgrade(private string) (error, string, string) { 17 | // 1. deploy proxy contract with private key 18 | fmt.Println("------------------------ begin deploy proxy ------------------------") 19 | var proxyAddr string 20 | adminAddr := keytools.GetAddressFromPrivateKey(util.DecodeHex(private)) 21 | proxyInit := []contract2.Value{ 22 | { 23 | VName: "_scilla_version", 24 | Type: "Uint32", 25 | Value: "0", 26 | }, { 27 | VName: "init_admin", 28 | Type: "ByStr20", 29 | Value: "0x" + adminAddr, 30 | }, { 31 | VName: "init_implementation", 32 | Type: "ByStr20", 33 | Value: "0x" + adminAddr, 34 | }, 35 | } 36 | data, _ := json.Marshal(proxyInit) 37 | jsonPath := "../contracts/proxy" + adminAddr + ".json" 38 | _ = ioutil.WriteFile(jsonPath, data, 0644) 39 | if err, output := ExecZli("contract", "deploy", 40 | "-k", private, 41 | "-c", "../contracts/proxy.scilla", 42 | "-i", jsonPath); err != nil { 43 | return err, "", "" 44 | } else { 45 | res := strings.Split(output, "contract address = ") 46 | res = strings.Split(res[1], "{") 47 | res = strings.Split(res[0], "track") 48 | proxyAddr = strings.TrimSpace(res[0]) 49 | } 50 | proxyBech32, _ := bech32.ToBech32Address(proxyAddr) 51 | fmt.Printf("proxy address = %s, bech32 = %s\n", proxyAddr, proxyBech32) 52 | fmt.Println("------------------------ end deploy proxy ------------------------") 53 | 54 | _ = os.Remove(jsonPath) 55 | 56 | // 2. deploy ssnlist contract with private key and proxy address 57 | fmt.Println("------------------------ begin deploy sshlist ------------------------") 58 | implInit := []contract2.Value{ 59 | { 60 | VName: "_scilla_version", 61 | Type: "Uint32", 62 | Value: "0", 63 | }, { 64 | VName: "init_admin", 65 | Type: "ByStr20", 66 | Value: "0x" + adminAddr, 67 | }, { 68 | VName: "proxy_address", 69 | Type: "ByStr20", 70 | Value: "0x" + proxyAddr, 71 | }, 72 | } 73 | data, _ = json.Marshal(implInit) 74 | fmt.Println(string(data)) 75 | jsonPath = "../contracts/ssnlist" + adminAddr + ".json" 76 | _ = ioutil.WriteFile(jsonPath, data, 0644) 77 | var sshlistAddr string 78 | 79 | if err, output := ExecZli("contract", "deploy", 80 | "-k", private, 81 | "-c", "../contracts/ssnlist.scilla", 82 | "-i", jsonPath); err != nil { 83 | return err, "", "" 84 | } else { 85 | res := strings.Split(output, "contract address = ") 86 | res = strings.Split(res[1], "{") 87 | res = strings.Split(res[0], "track") 88 | sshlistAddr = strings.TrimSpace(res[0]) 89 | } 90 | sshlistBech32, _ := bech32.ToBech32Address(sshlistAddr) 91 | fmt.Printf("ssnlist address = %s, bech32 = %s\n", sshlistAddr, sshlistBech32) 92 | fmt.Println("------------------------ end deploy sshlist ------------------------") 93 | 94 | _ = os.Remove(jsonPath) 95 | 96 | // 3. upgrade to actual implement 97 | fmt.Println("------------------------ start upgrade ------------------------") 98 | parameters := []contract2.Value{ 99 | { 100 | VName: "newImplementation", 101 | Type: "ByStr20", 102 | Value: "0x" + sshlistAddr, 103 | }, 104 | } 105 | args, _ := json.Marshal(parameters) 106 | fmt.Println(string(args)) 107 | if err2, output := ExecZli("contract", "call", 108 | "-k", private, 109 | "-a", proxyBech32, 110 | "-f","true", 111 | "-t", "upgradeTo", 112 | "-r", string(args)); err2 != nil { 113 | return err2, "", "" 114 | } else { 115 | //fmt.Println(output) 116 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 117 | fmt.Println("transaction id = ", tx) 118 | fmt.Println("------------------------ end upgrade ------------------------") 119 | return nil, proxyAddr, sshlistAddr 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /phase0/tests/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Zilliqa/gozilliqa-sdk v0.0.0-20200201085548-db590549f1ff h1:zKuqvBRyOb+7FOf39ac71GdGyjXZ5SIdXc5YquHtk/k= 2 | github.com/Zilliqa/gozilliqa-sdk v0.0.0-20200201085548-db590549f1ff/go.mod h1:o+YpwHxrU4nFnj0L+wS+bR+jl6h+IYBIR7wchcdGASE= 3 | github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= 4 | github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c h1:5N/b57wo2KfeHCGGdcXtOPsHqkPD+veLZhK/bMg2anQ= 5 | github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= 6 | github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= 7 | github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 8 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= 9 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 10 | github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= 11 | github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= 12 | github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 13 | github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= 14 | github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= 15 | github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 18 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 19 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 20 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 21 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 22 | github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 23 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 24 | github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 25 | github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= 26 | github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= 27 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 28 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 29 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 30 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 31 | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= 32 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 33 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 34 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 35 | github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= 36 | github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= 37 | github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ= 38 | github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= 39 | golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 40 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 41 | golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= 42 | golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 43 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 44 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 45 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 46 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 47 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 48 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 49 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 50 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 51 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 52 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 53 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 54 | -------------------------------------------------------------------------------- /phase0/scripts/NodeJS/Proxy-Admin/deploy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * deploy 3 | * deploys the proxy, staking contract, and upgrades the implementation 4 | */ 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const { BN, Long, bytes, units } = require('@zilliqa-js/util'); 8 | const { Zilliqa } = require('@zilliqa-js/zilliqa'); 9 | const { toBech32Address, getAddressFromPrivateKey } = require('@zilliqa-js/crypto'); 10 | 11 | // change the following parameters 12 | const API = 'http://localhost:5555' 13 | const CHAIN_ID = 1; 14 | const PRIVATE_KEY = 'e53d1c3edaffc7a7bab5418eb836cf75819a82872b4a1a0f1c7fcf5c3e020b89'; 15 | 16 | const zilliqa = new Zilliqa(API); 17 | const MSG_VERSION = 1; 18 | const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); 19 | const GAS_PRICE = units.toQa('1000', units.Units.Li); 20 | 21 | const PROXY_CONTRACT_PATH = "../../../contracts/proxy.scilla"; 22 | const SSNLIST_CONTRACT_PATH = "../../../contracts/ssnlist.scilla"; 23 | 24 | 25 | async function main() { 26 | try { 27 | zilliqa.wallet.addByPrivateKey(PRIVATE_KEY); 28 | const address = getAddressFromPrivateKey(PRIVATE_KEY); 29 | 30 | console.log("Your account address is:"); 31 | console.log(`${address}`); 32 | console.log("------------------------ begin deploy proxy ------------------------\n"); 33 | console.log(`Deploying proxy contract: ` + PROXY_CONTRACT_PATH); 34 | const code = fs.readFileSync(path.join(__dirname, PROXY_CONTRACT_PATH), 'ascii'); 35 | 36 | const init = [ 37 | { 38 | vname: "_scilla_version", 39 | type: "Uint32", 40 | value: "0", 41 | }, 42 | { 43 | vname: "init_admin", 44 | type: "ByStr20", 45 | value: `${address}` 46 | }, 47 | { 48 | vname: "init_implementation", 49 | type: "ByStr20", 50 | value: `${address}` 51 | } 52 | ]; 53 | const contract = zilliqa.contracts.new(code, init); 54 | const [deployTx, proxy] = await contract.deploy( 55 | { 56 | version: VERSION, 57 | amount: new BN(0), 58 | gasPrice: GAS_PRICE, 59 | gasLimit: Long.fromNumber(10000) 60 | }, 61 | 33, 62 | 1000, 63 | true 64 | ); 65 | 66 | // Introspect the state of the underlying transaction 67 | console.log(`Deployment Transaction ID: ${deployTx.id}`); 68 | console.log(`Deployment Transaction Receipt`); 69 | console.log(deployTx.txParams.receipt); 70 | console.log('proxy address: %o', proxy.address); 71 | console.log("------------------------ end deploy proxy ------------------------\n"); 72 | 73 | // deploy ssnlist contract 74 | console.log("------------------------ begin deploy ssnlist ------------------------\n"); 75 | console.log(`Deploying a ssnlist contract: %o`, SSNLIST_CONTRACT_PATH); 76 | const code2 = fs.readFileSync(path.join(__dirname, SSNLIST_CONTRACT_PATH), 'ascii'); 77 | 78 | const init2 = [ 79 | { 80 | vname: "_scilla_version", 81 | type: "Uint32", 82 | value: "0" 83 | }, 84 | { 85 | vname: "init_admin", 86 | type: "ByStr20", 87 | value: `${address}` 88 | }, 89 | { 90 | vname: "proxy_address", 91 | type: "ByStr20", 92 | value: `${proxy.address}` 93 | } 94 | ]; 95 | 96 | const contract2 = zilliqa.contracts.new(code2, init2); 97 | const [deployTx2, ssnlist] = await contract2.deploy( 98 | { 99 | version: VERSION, 100 | amount: new BN(0), 101 | gasPrice: GAS_PRICE, 102 | gasLimit: Long.fromNumber(30000) 103 | }, 104 | 33, 105 | 1000, 106 | true 107 | ); 108 | 109 | console.log(`Deployment ssnlist transaction ID: ${deployTx2.id}`); 110 | console.log(`Deployment ssnlist transaction receipt:`); 111 | console.log(deployTx2.txParams.receipt); 112 | console.log('ssnlist contract address: %o', ssnlist.address); 113 | console.log("------------------------ end deploy ssnlist ------------------------\n"); 114 | 115 | // upgrade proxy contract with ssn implementation 116 | console.log("------------------------ start upgrade ------------------------\n"); 117 | const callTx = await proxy.call( 118 | 'upgradeTo', 119 | [ 120 | { 121 | vname: 'newImplementation', 122 | type: 'ByStr20', 123 | value: `${ssnlist.address}` 124 | } 125 | ], 126 | { 127 | version: VERSION, 128 | amount: new BN(0), 129 | gasPrice: GAS_PRICE, 130 | gasLimit: Long.fromNumber(30000) 131 | }, 132 | 33, 133 | 1000, 134 | true 135 | ); 136 | console.log("transaction: %o", callTx.id); 137 | console.log(JSON.stringify(callTx.receipt, null, 4)); 138 | console.log("------------------------ end upgrade ------------------------\n"); 139 | } catch (err) { 140 | console.log(err); 141 | } 142 | } 143 | 144 | main(); -------------------------------------------------------------------------------- /tests/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210317065738-a18612ef8507 h1:C/Qzjxy1cYbJxenNUVoIiycF1aJdqHCOyHDSMtKTHcE= 2 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210317065738-a18612ef8507/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= 3 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210317092611-ce0a605f6227 h1:VYwhKs2VC3DVroa/WRGWVPpo7L7nIY9EQ4nCfrfL5FU= 4 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210317092611-ce0a605f6227/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= 5 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210319034641-0161a0c9e0fe h1:I4fA0k8B4Dg62WrgTspIlD6Y9e9ggza/VxI6emJLW8k= 6 | github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210319034641-0161a0c9e0fe/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= 7 | github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= 8 | github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c h1:5N/b57wo2KfeHCGGdcXtOPsHqkPD+veLZhK/bMg2anQ= 9 | github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= 10 | github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= 11 | github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 12 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= 13 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 14 | github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= 15 | github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= 16 | github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 17 | github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= 18 | github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= 19 | github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 20 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 21 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 22 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 23 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 24 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 25 | github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= 26 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 27 | github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 28 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 29 | github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 30 | github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= 31 | github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= 32 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 33 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 34 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 35 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 36 | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= 37 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 38 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 39 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 40 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 41 | github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= 42 | github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= 43 | github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ= 44 | github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= 45 | golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 46 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 47 | golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= 48 | golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 49 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 50 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 51 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 52 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 53 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 54 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 55 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 56 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 57 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 58 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 59 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 60 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 61 | -------------------------------------------------------------------------------- /phase0/tests/transitions/assign_stake_reward.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 8 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 9 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 10 | "github.com/Zilliqa/gozilliqa-sdk/util" 11 | "strings" 12 | ) 13 | 14 | // pri1 admin and verifier 15 | // pri2 aan operator 16 | func TestAssignStakeReward(pri1, pri2, api string) { 17 | fmt.Println("------------------------ start AssignStakeReward ------------------------") 18 | // 0. setup 19 | err, proxy, impl := DeployAndUpgrade(pri1) 20 | if err != nil { 21 | panic("got error = " + err.Error()) 22 | } 23 | fmt.Println("proxy = ", proxy) 24 | fmt.Println("impl = ", impl) 25 | p := NewProxy(api, proxy, impl) 26 | err2 := p.updateVerifier(pri1) 27 | if err2 != nil { 28 | panic("test assign stake reward failed: update verifier error: " + err2.Error()) 29 | } 30 | 31 | _ = p.updateStakingParameter(pri1, "1000000000", "5000000000", "100000000000000000") 32 | 33 | 34 | ssn1 := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri1)) 35 | ssn2 := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri2)) 36 | 37 | if err0 := p.unpause(pri1); err0 != nil { 38 | panic("unpause with valid account failed") 39 | } 40 | // 1. assign ssn1, should fail 41 | err1 := p.assignStakeReward(pri1, ssn1, "50") 42 | if err1 == nil { 43 | panic("test assign stake with non-ssn reward failed") 44 | } else { 45 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 46 | sshmap := res["ssnlist"].(map[string]interface{}) 47 | ssn := sshmap[ssn1] 48 | if ssn == nil { 49 | fmt.Println("test assign stake with non-ssn reward succeed") 50 | } else { 51 | panic("test assign stake with non-ssn reward failed") 52 | } 53 | } 54 | 55 | // 2. add ssn1, ssn2 56 | parameters := []contract2.Value{ 57 | { 58 | VName: "ssnaddr", 59 | Type: "ByStr20", 60 | Value: ssn1, 61 | }, 62 | { 63 | VName: "stake_amount", 64 | Type: "Uint128", 65 | Value: "100000000000", 66 | }, 67 | { 68 | VName: "rewards", 69 | Type: "Uint128", 70 | Value: "0", 71 | }, 72 | { 73 | VName: "urlraw", 74 | Type: "String", 75 | Value: "devapiziiliqacom", 76 | }, 77 | { 78 | VName: "urlapi", 79 | Type: "String", 80 | Value: "ziiliqacom", 81 | }, 82 | { 83 | VName: "buffered_deposit", 84 | Type: "Uint128", 85 | Value: "1000", 86 | }, 87 | } 88 | args, _ := json.Marshal(parameters) 89 | if err3, output := ExecZli("contract", "call", 90 | "-k", pri1, 91 | "-a", proxy, 92 | "-t", "add_ssn_after_upgrade", 93 | "-f", "true", 94 | "-r", string(args)); err3 != nil { 95 | panic("call transaction error: " + err3.Error()) 96 | } else { 97 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 98 | fmt.Println("transaction id = ", tx) 99 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 100 | receipt := payload["receipt"].(map[string]interface{}) 101 | success := receipt["success"].(bool) 102 | if success { 103 | fmt.Println("add ssn1 succeed") 104 | } else { 105 | panic("add ssn1 failed") 106 | } 107 | } 108 | 109 | parameters = []contract2.Value{ 110 | { 111 | VName: "ssnaddr", 112 | Type: "ByStr20", 113 | Value: ssn2, 114 | }, 115 | { 116 | VName: "stake_amount", 117 | Type: "Uint128", 118 | Value: "100000000000", 119 | }, 120 | { 121 | VName: "rewards", 122 | Type: "Uint128", 123 | Value: "0", 124 | }, 125 | { 126 | VName: "urlraw", 127 | Type: "String", 128 | Value: "devapiziiliqacom2", 129 | }, 130 | { 131 | VName: "urlapi", 132 | Type: "String", 133 | Value: "ziiliqacom2", 134 | }, 135 | { 136 | VName: "buffered_deposit", 137 | Type: "Uint128", 138 | Value: "0", 139 | }, 140 | } 141 | args, _ = json.Marshal(parameters) 142 | if err3, output := ExecZli("contract", "call", 143 | "-k", pri1, 144 | "-a", proxy, 145 | "-t", "add_ssn_after_upgrade", 146 | "-f", "true", 147 | "-r", string(args)); err3 != nil { 148 | panic("call transaction error: " + err3.Error()) 149 | } else { 150 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 151 | fmt.Println("transaction id = ", tx) 152 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 153 | receipt := payload["receipt"].(map[string]interface{}) 154 | success := receipt["success"].(bool) 155 | if success { 156 | fmt.Println("add ssn2 succeed") 157 | } else { 158 | panic("add ssn2 failed") 159 | } 160 | } 161 | 162 | // check totalstakedeposit 163 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 164 | totalstakedeposit := res["totalstakedeposit"].(string) 165 | if totalstakedeposit != "200000001000" { 166 | panic("check totalstakedeposit error") 167 | } 168 | 169 | // 3. reward ssn1 170 | err = p.assignStakeReward(pri1, ssn1, "50") 171 | if err != nil { 172 | panic("reward ssn1 failed: " + err.Error()) 173 | } 174 | res = p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 175 | sshmap := res["ssnlist"].(map[string]interface{}) 176 | ssn := sshmap[ssn1] 177 | if ssn == nil { 178 | panic("reward ssn1 failed") 179 | } else { 180 | arguments := ssn.(map[string]interface{})["arguments"].([]interface{})[2].(string) 181 | if arguments != "5000" { 182 | panic("reward ssn1 failed: state check error") 183 | } else { 184 | fmt.Println("reward ssn1 succeed") 185 | } 186 | } 187 | 188 | ssn = sshmap[ssn2] 189 | if ssn == nil { 190 | panic("_reward ssn2 failed") 191 | } else { 192 | arguments := ssn.(map[string]interface{})["arguments"].([]interface{})[2].(string) 193 | if arguments == "0" { 194 | fmt.Println("_reward ssn2 succeed") 195 | } else { 196 | panic("_reward ssn2 failed: state check error") 197 | } 198 | } 199 | 200 | // 4. reward ssn2 201 | err = p.assignStakeReward(pri1, ssn2, "50") 202 | if err != nil { 203 | panic("reward ssn2 failed: " + err.Error()) 204 | } 205 | res = p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 206 | sshmap = res["ssnlist"].(map[string]interface{}) 207 | ssn = sshmap[ssn2] 208 | if ssn == nil { 209 | panic("reward ssn2 failed") 210 | } else { 211 | arguments := ssn.(map[string]interface{})["arguments"].([]interface{})[2].(string) 212 | if arguments != "5000" { 213 | panic("reward ssn2 failed: state check error") 214 | } else { 215 | fmt.Println("reward ssn2 succeed") 216 | } 217 | } 218 | } 219 | 220 | func (p *Proxy) assignStakeReward(pri, ssn, percent string) error { 221 | proxy, _ := bech32.ToBech32Address(p.Addr) 222 | val := []Val{ 223 | { 224 | Constructor: "SsnRewardShare", 225 | ArgTypes: make([]interface{}, 0), 226 | Arguments: []string{ssn, percent}, 227 | }, 228 | } 229 | parameters := []contract2.Value{ 230 | { 231 | VName: "ssnreward_list", 232 | Type: "List SsnRewardShare", 233 | Value: val, 234 | }, 235 | { 236 | VName: "reward_blocknum", 237 | Type: "Uint32", 238 | Value: "50000", 239 | }, 240 | } 241 | 242 | args, _ := json.Marshal(parameters) 243 | 244 | if err2, output := ExecZli("contract", "call", 245 | "-k", pri, 246 | "-a", proxy, 247 | "-t", "assign_stake_reward", 248 | "-f", "true", 249 | "-r", string(args)); err2 != nil { 250 | return errors.New("call transition error: " + err2.Error()) 251 | } else { 252 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 253 | fmt.Println("transaction id = ", tx) 254 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 255 | receipt := payload["receipt"].(map[string]interface{}) 256 | success := receipt["success"].(bool) 257 | if success { 258 | return nil 259 | } else { 260 | return errors.New("transaction failed: " + tx) 261 | } 262 | } 263 | } 264 | 265 | type Val struct { 266 | Constructor string `json:"constructor"` 267 | ArgTypes []interface{} `json:"argtypes"` 268 | Arguments []string `json:"arguments"` 269 | } 270 | -------------------------------------------------------------------------------- /phase0/tests/transitions/add_ssn.go: -------------------------------------------------------------------------------- 1 | package transitions 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 9 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 10 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 11 | "github.com/Zilliqa/gozilliqa-sdk/util" 12 | ) 13 | 14 | // since this serial of test is complicated, so we test them on new fresh contracts 15 | // so we deploy and upgrade first 16 | func TestAddSSN(pri1, pri2 string, api string) { 17 | fmt.Println("------------------------ start AddSSN ------------------------") 18 | err, proxy, impl := DeployAndUpgrade(pri1) 19 | if err != nil { 20 | panic("got error = " + err.Error()) 21 | } 22 | fmt.Println("proxy = ", proxy) 23 | fmt.Println("impl = ", impl) 24 | p := NewProxy(api, proxy, impl) 25 | p.AddSSN(pri1, pri2) 26 | } 27 | 28 | func (p *Proxy) AddSSN(pri1, pri2 string) { 29 | if err1 := p.unpause(pri1); err1 != nil { 30 | panic("unpause with valid account failed") 31 | } 32 | // 1. as and non-admin to add ssn, should fail 33 | proxy, _ := bech32.ToBech32Address(p.Addr) 34 | ssnaddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri2)) 35 | parameters := []contract2.Value{ 36 | { 37 | VName: "ssnaddr", 38 | Type: "ByStr20", 39 | Value: ssnaddr, 40 | }, 41 | { 42 | VName: "urlraw", 43 | Type: "String", 44 | Value: "devapiziiliqacom", 45 | }, 46 | { 47 | VName: "urlapi", 48 | Type: "String", 49 | Value: "ziiliqacom", 50 | }, 51 | } 52 | args, _ := json.Marshal(parameters) 53 | if err2, output := ExecZli("contract", "call", 54 | "-k", pri2, 55 | "-a", proxy, 56 | "-t", "add_ssn", 57 | "-f", "true", 58 | "-r", string(args)); err2 != nil { 59 | panic("call transaction error: " + err2.Error()) 60 | } else { 61 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 62 | fmt.Println("transaction id = ", tx) 63 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 64 | receipt := payload["receipt"].(map[string]interface{}) 65 | success := receipt["success"].(bool) 66 | if success { 67 | panic("test add ssn with non-verifier failed") 68 | } else { 69 | fmt.Println("test add ssn with non-verifier succeed") 70 | } 71 | } 72 | 73 | // 3.1 add account2 to ssn list 74 | if err3, output := ExecZli("contract", "call", 75 | "-k", pri1, 76 | "-a", proxy, 77 | "-t", "add_ssn", 78 | "-f", "true", 79 | "-r", string(args)); err3 != nil { 80 | panic("call transaction error: " + err3.Error()) 81 | } else { 82 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 83 | fmt.Println("transaction id = ", tx) 84 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 85 | receipt := payload["receipt"].(map[string]interface{}) 86 | success := receipt["success"].(bool) 87 | if success { 88 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 89 | sshList, ok := res["ssnlist"] 90 | if !ok { 91 | panic("test add ssn with verifier failed check state failed: no ssnlist") 92 | } 93 | ssn, ok := sshList.(map[string]interface{})[ssnaddr] 94 | if !ok { 95 | panic("test add ssn with verifier failed check state failed: no such ssn") 96 | } 97 | deposit := ssn.(map[string]interface{})["arguments"].([]interface{})[1].(string) 98 | if deposit != "0" { 99 | panic("test add ssn with verifier failed check state failed: deposit not equal to zero") 100 | } 101 | 102 | inactive := ssn.(map[string]interface{})["arguments"].([]interface{})[0].(map[string]interface{})["constructor"] 103 | if inactive == "True" { 104 | panic("test add ssn with verifier failed check state failed: deposit are active,should be inactive") 105 | } else { 106 | fmt.Println("test add ssn with verifier succeed") 107 | } 108 | } else { 109 | panic("test add ssn with verifier failed") 110 | } 111 | 112 | // 3.3 add ssn once again 113 | if err3, output := ExecZli("contract", "call", 114 | "-k", pri1, 115 | "-a", proxy, 116 | "-t", "add_ssn", 117 | "-f", "true", 118 | "-r", string(args)); err3 != nil { 119 | panic("call transaction error: " + err3.Error()) 120 | } else { 121 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 122 | fmt.Println("transaction id = ", tx) 123 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 124 | receipt := payload["receipt"].(map[string]interface{}) 125 | success := receipt["success"].(bool) 126 | if !success { 127 | fmt.Println("test add ssn twice succeed") 128 | } else { 129 | panic("test add ssn twice succeed failed") 130 | } 131 | } 132 | 133 | // 3.4 remove an nonexistent 134 | parameters := []contract2.Value{ 135 | { 136 | VName: "ssnaddr", 137 | Type: "ByStr20", 138 | Value: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 139 | }, 140 | } 141 | args, _ := json.Marshal(parameters) 142 | if err3, output := ExecZli("contract", "call", 143 | "-k", pri1, 144 | "-a", proxy, 145 | "-t", "remove_ssn", 146 | "-f", "true", 147 | "-r", string(args)); err3 != nil { 148 | panic("call transaction error: " + err3.Error()) 149 | } else { 150 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 151 | fmt.Println("transaction id = ", tx) 152 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 153 | receipt := payload["receipt"].(map[string]interface{}) 154 | success := receipt["success"].(bool) 155 | if !success { 156 | fmt.Println("test remove nonexistent ssn succeed") 157 | } else { 158 | panic("test remove nonexistent ssn failed") 159 | } 160 | } 161 | 162 | // 4 remove with admin 163 | // 4.1 change admin to pri2 164 | err := p.updateAdmin(pri1, pri2) 165 | if err != nil { 166 | panic("change admin error: " + err.Error()) 167 | } 168 | 169 | // 4.2 remove exist ssn 170 | parameters = []contract2.Value{ 171 | { 172 | VName: "ssnaddr", 173 | Type: "ByStr20", 174 | Value: ssnaddr, 175 | }, 176 | } 177 | args, _ = json.Marshal(parameters) 178 | if err3, output := ExecZli("contract", "call", 179 | "-k", pri2, 180 | "-a", proxy, 181 | "-t", "remove_ssn", 182 | "-f", "true", 183 | "-r", string(args)); err3 != nil { 184 | panic("call transaction error: " + err3.Error()) 185 | } else { 186 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 187 | fmt.Println("transaction id = ", tx) 188 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 189 | receipt := payload["receipt"].(map[string]interface{}) 190 | success := receipt["success"].(bool) 191 | if success { 192 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 193 | r, _ := json.Marshal(res) 194 | fmt.Println(string(r)) 195 | ssnList, _ := res["ssnlist"] 196 | ssnMap := ssnList.(map[string]interface{}) 197 | ssn := ssnMap[ssnaddr] 198 | if ssn == nil { 199 | fmt.Println("test remove ssn succees") 200 | } else { 201 | fmt.Println("test remove ssn failed: check state failed") 202 | } 203 | 204 | } else { 205 | panic("test remove ssn failed") 206 | } 207 | } 208 | 209 | // 4.3 remove the same ssn again, reuse the same parameters as (4.2) 210 | args, _ = json.Marshal(parameters) 211 | if err3, output := ExecZli("contract", "call", 212 | "-k", pri2, 213 | "-a", proxy, 214 | "-t", "remove_ssn", 215 | "-f", "true", 216 | "-r", string(args)); err3 != nil { 217 | panic("call transaction error: " + err3.Error()) 218 | } else { 219 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 220 | fmt.Println("transaction id = ", tx) 221 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 222 | receipt := payload["receipt"].(map[string]interface{}) 223 | success := receipt["success"].(bool) 224 | 225 | if !success { 226 | fmt.Println("test remove same ssn address succeed") 227 | } else { 228 | panic("test remove same ssn address failed") 229 | } 230 | } 231 | } 232 | 233 | fmt.Println("------------------------ end AddSSN ------------------------") 234 | } 235 | -------------------------------------------------------------------------------- /phase0/tests/transitions/remove_ssn.go: -------------------------------------------------------------------------------- 1 | // 2 | // test: remove_deposit 3 | // 4 | package transitions 5 | 6 | import ( 7 | "encoding/json" 8 | "fmt" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/Zilliqa/gozilliqa-sdk/keytools" 13 | "github.com/Zilliqa/gozilliqa-sdk/util" 14 | 15 | "github.com/Zilliqa/gozilliqa-sdk/bech32" 16 | contract2 "github.com/Zilliqa/gozilliqa-sdk/contract" 17 | ) 18 | 19 | 20 | func TestRemoveSSN(pri1, pri2 string, api string) { 21 | fmt.Println("------------------------ start remove ssn ------------------------") 22 | err, proxy, impl := DeployAndUpgrade(pri1) 23 | if err != nil { 24 | panic("got error = " + err.Error()) 25 | } 26 | fmt.Println("proxy = ", proxy) 27 | fmt.Println("impl = ", impl) 28 | p := NewProxy(api, proxy, impl) 29 | p.RemoveSSN(pri1, pri2, api) 30 | } 31 | 32 | func (p *Proxy) RemoveSSN(pri1, pri2 string, api string) { 33 | if err0 := p.unpause(pri1); err0 != nil { 34 | panic("unpause with valid account failed") 35 | } 36 | // 0. setup minstake maxstake contractmaxstake 37 | err := p.updateStakingParameter(pri1, strconv.Itoa(MIN_STAKE), strconv.Itoa(MAX_STAKE), strconv.Itoa(CONTRACT_MAX_STAKE)) 38 | if err != nil { 39 | panic("update staking parameter error: " + err.Error()) 40 | } 41 | err = p.updateVerifier(pri1) 42 | if err != nil { 43 | panic("update verifier error: " + err.Error()) 44 | } 45 | 46 | 47 | // 1. add pri2 as ssn 48 | ssnaddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri2)) 49 | p.RegisterSSN(pri1, ssnaddr) 50 | 51 | proxy, _ := bech32.ToBech32Address(p.Addr) 52 | 53 | // 2. as ssn, first time stake deposit (MIN_STAKE + 1) 54 | if err3, output := ExecZli("contract", "call", 55 | "-k", pri2, 56 | "-a", proxy, 57 | "-t", "stake_deposit", 58 | "-m", strconv.Itoa(MIN_STAKE+1), 59 | "-f", "true", 60 | "-r", "[]"); err3 != nil { 61 | panic("call transaction error: " + err3.Error()) 62 | } else { 63 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 64 | fmt.Println("transaction id = ", tx) 65 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 66 | receipt := payload["receipt"].(map[string]interface{}) 67 | success := receipt["success"].(bool) 68 | eventLogs := receipt["event_logs"].([]interface{})[0] 69 | if success { 70 | events := eventLogs.(map[string]interface{}) 71 | eventName := events["_eventname"].(string) 72 | 73 | if eventName == "SSN updated stake" { 74 | ssnAddr := events["params"].([]interface{})[0].(map[string]interface{})["value"].(string) 75 | newStakeAmount := events["params"].([]interface{})[1].(map[string]interface{})["value"].(string) 76 | expectedSSNAddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri2)) 77 | expectedStakeAmount := strconv.Itoa(MIN_STAKE + 1) 78 | 79 | if ssnAddr != expectedSSNAddr { 80 | panic("test first time stake deposit failed, tx:" + tx + " , returned ssn: " + ssnAddr + " , expected ssn: " + expectedSSNAddr) 81 | } 82 | if newStakeAmount != expectedStakeAmount { 83 | panic("test first time stake deposit failed, tx:" + tx + " , returned stake amount: " + newStakeAmount + " , expected stake amount: " + expectedStakeAmount) 84 | } 85 | 86 | // check ssn active status 87 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 88 | ssnmap := res["ssnlist"].(map[string]interface{}) 89 | ssn := ssnmap[ssnAddr] 90 | 91 | if ssn == nil { 92 | panic("test first time stake deposit failed, tx:" + tx) 93 | } else { 94 | ssnStatus := ssn.(map[string]interface{})["arguments"].([]interface{})[0].(map[string]interface{})["constructor"].(string) 95 | if ssnStatus == "Active" { 96 | fmt.Println("test first time stake deposit succeed") 97 | } else { 98 | panic("test first time stake deposit failed, tx:" + tx) 99 | } 100 | } 101 | 102 | } else { 103 | panic("test first time stake deposit failed, tx:" + tx) 104 | } 105 | } else { 106 | panic("test stake deposit below min stake limit error, tx:" + tx) 107 | } 108 | } 109 | 110 | // 3. after first time deposit, deposit min_stake + 1 111 | if err3, output := ExecZli("contract", "call", 112 | "-k", pri2, 113 | "-a", proxy, 114 | "-t", "stake_deposit", 115 | "-m", strconv.Itoa(MIN_STAKE+1), 116 | "-f", "true", 117 | "-r", "[]"); err3 != nil { 118 | panic("call transaction error: " + err3.Error()) 119 | } else { 120 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 121 | fmt.Println("transaction id = ", tx) 122 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 123 | receipt := payload["receipt"].(map[string]interface{}) 124 | success := receipt["success"].(bool) 125 | if success { 126 | // no event output after the first time stake deposit 127 | // check ssn active status 128 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 129 | totalStakeDeposit := res["totalstakedeposit"].(string) 130 | expectedTotalStakeDeposit := strconv.Itoa((MIN_STAKE + 1) * 2) 131 | ssnmap := res["ssnlist"].(map[string]interface{}) 132 | ssnAddr := "0x" + keytools.GetAddressFromPrivateKey(util.DecodeHex(pri2)) 133 | ssn := ssnmap[ssnAddr] 134 | 135 | // this is the second time depositing (min stake + 1) 136 | if totalStakeDeposit != expectedTotalStakeDeposit { 137 | panic("test stake deposit (after first time deposit) failed, tx:" + tx + " , total stake deposit:" + totalStakeDeposit + " , expected:" + expectedTotalStakeDeposit) 138 | } 139 | 140 | if ssn == nil { 141 | panic("test stake deposit (after first time deposit) error, tx:" + tx) 142 | } else { 143 | ssnStatus := ssn.(map[string]interface{})["arguments"].([]interface{})[0].(map[string]interface{})["constructor"].(string) 144 | if ssnStatus == "Active" { 145 | fmt.Println("test stake deposit (after first time deposit) succeed") 146 | } else { 147 | panic("test stake deposit (after first time deposit) error, tx:" + tx) 148 | } 149 | } 150 | 151 | } else { 152 | panic("test stake deposit (after first time deposit) error, tx:" + tx) 153 | } 154 | } 155 | 156 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 157 | r, _ := json.Marshal(res) 158 | fmt.Println("before removing: ",string(r)) 159 | 160 | 161 | // 4.6 remove ssn 162 | m := p.Provider.GetBalance(p.ImplAddress).Result.(map[string]interface{}) 163 | before := m["balance"].(string) 164 | fmt.Println("balance bofore removing ssn: ",before) 165 | 166 | // 4.2 remove exist ssn 167 | parameters := []contract2.Value{ 168 | { 169 | VName: "ssnaddr", 170 | Type: "ByStr20", 171 | Value: ssnaddr, 172 | }, 173 | } 174 | args, _ := json.Marshal(parameters) 175 | if err3, output := ExecZli("contract", "call", 176 | "-k", pri1, 177 | "-a", proxy, 178 | "-t", "remove_ssn", 179 | "-f", "true", 180 | "-r", string(args)); err3 != nil { 181 | panic("call transaction error: " + err3.Error()) 182 | } else { 183 | tx := strings.TrimSpace(strings.Split(output, "confirmed!")[1]) 184 | fmt.Println("transaction id = ", tx) 185 | payload := p.Provider.GetTransaction(tx).Result.(map[string]interface{}) 186 | receipt := payload["receipt"].(map[string]interface{}) 187 | success := receipt["success"].(bool) 188 | if success { 189 | res := p.Provider.GetSmartContractState(p.ImplAddress).Result.(map[string]interface{}) 190 | r, _ = json.Marshal(res) 191 | fmt.Println(string(r)) 192 | ssnList, _ := res["ssnlist"] 193 | ssnMap := ssnList.(map[string]interface{}) 194 | ssn := ssnMap[ssnaddr] 195 | totalstakedeposit := res["totalstakedeposit"].(string) 196 | if ssn == nil && totalstakedeposit == "0" { 197 | m = p.Provider.GetBalance(p.ImplAddress).Result.(map[string]interface{}) 198 | after := m["balance"].(string) 199 | if after != "0" { 200 | panic("check balance failed") 201 | } 202 | 203 | } else { 204 | fmt.Println("test remove ssn failed: check state failed") 205 | } 206 | 207 | } else { 208 | panic("test remove ssn failed") 209 | } 210 | } 211 | 212 | fmt.Println("------------------------ end remove ssn ------------------------") 213 | 214 | } -------------------------------------------------------------------------------- /phase0/contracts/proxy.scilla: -------------------------------------------------------------------------------- 1 | scilla_version 0 2 | 3 | library SSNListProxy 4 | 5 | let zero = Uint128 0 6 | let multisig_tag_addfunds = "AddFunds" 7 | 8 | 9 | let one_msg = 10 | fun (m : Message) => 11 | let e = Nil {Message} in 12 | Cons {Message} m e 13 | 14 | type SsnRewardShare = 15 | | SsnRewardShare of ByStr20 Uint128 16 | 17 | (***************************************************) 18 | (* The contract definition *) 19 | (***************************************************) 20 | 21 | (* Roles in this contract *) 22 | (* init_admin: Initial admin during deployment of this contract *) 23 | (* admin: Current admin of contract. For updating of admin, implementation address and draining contract balances *) 24 | 25 | contract SSNListProxy( 26 | init_implementation : ByStr20, 27 | init_admin : ByStr20 28 | ) 29 | 30 | (* Mutable fields *) 31 | 32 | field implementation : ByStr20 = init_implementation 33 | field admin : ByStr20 = init_admin 34 | 35 | procedure TransferFunds (tag: String, amount : Uint128, recipient : ByStr20) 36 | msg = {_tag : tag; _recipient : recipient; _amount : amount}; 37 | msgs = one_msg msg; 38 | send msgs 39 | end 40 | 41 | transition upgradeTo(newImplementation : ByStr20) 42 | currentAdmin <- admin; 43 | isAdmin = builtin eq currentAdmin _sender; 44 | match isAdmin with 45 | | True => 46 | implementation := newImplementation; 47 | e = {_eventname : "Upgraded"; implementation_address : newImplementation}; 48 | event e 49 | | False => 50 | e = {_eventname : "upgradeTo FailedNotAdmin"; newImplementation : newImplementation}; 51 | event e 52 | end 53 | end 54 | 55 | transition changeProxyAdmin(newAdmin : ByStr20) 56 | currentAdmin <- admin; 57 | isAdmin = builtin eq currentAdmin _sender; 58 | match isAdmin with 59 | | True => 60 | admin := newAdmin; 61 | e = {_eventname : "AdminChanged"; oldAdmin : currentAdmin; newAdmin : newAdmin}; 62 | event e 63 | | False => 64 | e = {_eventname : "changeAdmin FailedNotAdmin"; newAdmin : newAdmin}; 65 | event e 66 | end 67 | end 68 | 69 | transition drainProxyContractBalance() 70 | currentAdmin <- admin; 71 | isAdmin = builtin eq currentAdmin _sender; 72 | match isAdmin with 73 | | True => 74 | bal <- _balance; 75 | TransferFunds multisig_tag_addfunds bal _sender; 76 | e = {_eventname : "drainProxyContractBalance"}; 77 | event e 78 | | False => 79 | e = {_exception : "drainProxyContractBalance FailedNotAdmin"}; 80 | throw e 81 | end 82 | end 83 | 84 | transition pause() 85 | current_impl <- implementation; 86 | msg = {_tag : "pause"; _recipient : current_impl; _amount : zero; initiator : _sender}; 87 | msgs = one_msg msg; 88 | send msgs 89 | end 90 | 91 | transition unpause() 92 | current_impl <- implementation; 93 | msg = {_tag : "unpause"; _recipient : current_impl; _amount : zero; initiator : _sender}; 94 | msgs = one_msg msg; 95 | send msgs 96 | end 97 | 98 | 99 | transition update_admin (admin : ByStr20) 100 | current_impl <- implementation; 101 | msg = {_tag : "update_admin"; _recipient : current_impl; _amount : zero; admin : admin; initiator : _sender}; 102 | msgs = one_msg msg; 103 | send msgs 104 | end 105 | 106 | (* @dev: Set the verifier of contract. Used by admin only. *) 107 | (* @param verif: New verifier value *) 108 | transition update_verifier (verif : ByStr20) 109 | current_impl <- implementation; 110 | msg = {_tag : "update_verifier"; _recipient : current_impl; _amount : zero; verif : verif; initiator : _sender}; 111 | msgs = one_msg msg; 112 | send msgs 113 | end 114 | 115 | (* @dev: Drain the balance of the contract. Used by current admin only. *) 116 | transition drain_contract_balance () 117 | current_impl <- implementation; 118 | msg = {_tag : "drain_contract_balance"; _recipient : current_impl; _amount : zero; initiator : _sender}; 119 | msgs = one_msg msg; 120 | send msgs 121 | end 122 | 123 | (* @dev: Set the minstake, maxstake and contract maxstake of contract. Used by admin only. *) 124 | (* @param min_stake: New min_stake value *) 125 | (* @param max_stake: New maxstake value *) 126 | (* @param contract_max_stake: New contract_max_stake value *) 127 | transition update_staking_parameter (min_stake : Uint128, max_stake : Uint128, contract_max_stake : Uint128) 128 | current_impl <- implementation; 129 | msg = {_tag : "update_staking_parameter"; _recipient : current_impl; _amount : zero; min_stake : min_stake; max_stake : max_stake; contract_max_stake : contract_max_stake; initiator : _sender}; 130 | msgs = one_msg msg; 131 | send msgs 132 | end 133 | 134 | (* @dev: Adds new ssn to ssnlist. Used by admin only. *) 135 | (* @param ssnaddr: Address of the ssn to be added *) 136 | (* @param stake_amount: Stake amount of ssn *) 137 | (* @param urlraw: string representing "ip:port" of the ssn serving raw api request *) 138 | (* @param urlapi: string representing url exposed by ssn serving public api request *) 139 | transition add_ssn (ssnaddr : ByStr20, urlraw : String, urlapi : String) 140 | current_impl <- implementation; 141 | msg = {_tag : "add_ssn"; _recipient : current_impl; _amount : zero; ssnaddr: ssnaddr; urlraw: urlraw; urlapi: urlapi; initiator : _sender}; 142 | msgs = one_msg msg; 143 | send msgs 144 | end 145 | 146 | transition add_ssn_after_upgrade (ssnaddr : ByStr20, stake_amount : Uint128, rewards : Uint128, urlraw : String, urlapi : String, buffered_deposit : Uint128) 147 | current_impl <- implementation; 148 | msg = {_tag : "add_ssn_after_upgrade"; _recipient : current_impl; _amount : zero; ssnaddr: ssnaddr; stake_amount : stake_amount; rewards: rewards; urlraw: urlraw; urlapi: urlapi; buffered_deposit: buffered_deposit; initiator : _sender}; 149 | msgs = one_msg msg; 150 | send msgs 151 | end 152 | 153 | (* @dev: Remove a specific ssn from ssnlist. Used by verifier only. *) 154 | (* @param ssnaddr: Address of the ssn to be removed *) 155 | transition remove_ssn (ssnaddr : ByStr20) 156 | current_impl <- implementation; 157 | msg = {_tag : "remove_ssn"; _recipient : current_impl; _amount : zero; ssnaddr: ssnaddr; initiator : _sender}; 158 | msgs = one_msg msg; 159 | send msgs 160 | end 161 | 162 | 163 | (* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. i.e. ssn *) 164 | (* @dev: Stake amount of exisitng ssn in ssnlist will be updated with new amount only if existing stake amount is 0. 165 | Balance of contract account will increase. Balance of _sender will decrease. *) 166 | transition stake_deposit () 167 | current_impl <- implementation; 168 | accept; 169 | msg = {_tag : "stake_deposit"; _recipient : current_impl; _amount : _amount; initiator : _sender}; 170 | msgs = one_msg msg; 171 | send msgs 172 | end 173 | 174 | (* @dev: Assign stake reward to all ssn from ssnlist. Used by verifier only. *) 175 | (* @param ssnrewardlist: List of SsnRewardShare *) 176 | (* @param reward_blocknum: tx block num when ssns were verified *) 177 | transition assign_stake_reward (ssnreward_list : List SsnRewardShare, reward_blocknum : Uint32) 178 | current_impl <- implementation; 179 | msg = {_tag : "assign_stake_reward"; _recipient : current_impl; _amount : zero; ssnreward_list: ssnreward_list; reward_blocknum : reward_blocknum; initiator : _sender}; 180 | msgs = one_msg msg; 181 | send msgs 182 | end 183 | 184 | 185 | (* @dev: Withdraw stake reward. Used by ssn only. *) 186 | transition withdraw_stake_rewards () 187 | current_impl <- implementation; 188 | msg = {_tag : "withdraw_stake_rewards"; _recipient : current_impl; _amount : zero; initiator : _sender}; 189 | msgs = one_msg msg; 190 | send msgs 191 | end 192 | 193 | (* @dev: Move token amount from contract account to _sender. Used by ssn only. *) 194 | (* @param amount: token amount to be withdrawed *) 195 | transition withdraw_stake_amount (amount : Uint128 ) 196 | current_impl <- implementation; 197 | msg = {_tag : "withdraw_stake_amount"; _recipient : current_impl; _amount : zero; amount: amount; initiator : _sender}; 198 | msgs = one_msg msg; 199 | send msgs 200 | end 201 | 202 | (* @dev: Move token amount from _sender to recipient i.e. contract address. *) 203 | transition AddFunds () 204 | current_impl <- implementation; 205 | accept; 206 | msg = {_tag : "AddFunds"; _recipient : current_impl; _amount : _amount; initiator : _sender}; 207 | msgs = one_msg msg; 208 | send msgs 209 | end --------------------------------------------------------------------------------