Install Golang 1.15+ following instructions from https://golang.org/doc/install.
Install Solidity Compiler following instructions from https://solidity.readthedocs.io/en/latest/installing-solidity.html#binary-packages.
Install solc first to make CVM transactions.
-
Mechanically copied code (that we intend to copy again in the future) from external dependencies should be kept in original style as close as possible.
-
All exported definitions (types, methods, functions, variables, constants, etc.) should have whole sentence comments starting with the definition name.
-
Group imports in the following order, separated by an empty line in between.
- Standard packages
- Other 3rd-party packages
- Tendermint packages
- Cosmos SDK packages
- Burrow packages
- Shentu packages
-
Before creating pull requests of your changes, run the following commandlines for style and dependencies.
$ make tidy
Also make sure to fix linter and testing errors.
$ make lint $ make testgolangci-lint needs to be installed locally to run the linters.
To include the built binary to GOBIN,
$ make installTo build for Windows, Linux, and macOS,
$ make releaseRun unit test:
$ make testRun unit test and view brief coverage in cli:
$ make test-covRun unit test and view detailed coverage report in browser:
$ make test-cov-html$ make imageThis builds the docker image for the shentu node daemon & client. (Note that this command needs to be run prior to the multi node testnet setup below.)
Run make image first to build the images initially (no need to be rerun for usual code update).
Setup a localnet (per code change):
$ make localnet-startThis will run (four) testnet nodes in the background as well as an interactive client. If you want to see node output, do docker-compose logs -f (in other terminal) which will display output from all four nodes until you exit the process. Stops the localnet by docker-compose down.
To access the running localnet machine, you can list the running containers through
docker container ls --alland access the specific container through
docker exec -it <container name> /bin/bashRun the scripts for testing:
$ shentud query account $NODE0_KEY
$ shentud query bank total
# Create a new account
$ shentud keys add jack
$ JACK_KEY=$(shentud keys show jack -a)
# default password = jkljkljkl
$ shentud tx send node0 $JACK_KEY 100000uctk --gas-prices=0.025uctk --from node0
$ shentud query account $JACK_KEYFinally, run make localnet-stop to shutdown the localnet.
Please see e2e/README.md for instructions.
Recommend the use of the provided Docker containers for simplicity, but here are instructions for manually setting up a single node chain for testing purposes.
$ shentud unsafe-reset-all
$ rm -rf ~/.shentud
$ shentud init node0 --chain-id shentuchain
$ shentud keys add jack
$ shentud add-genesis-account $(shentud keys show jack -a) 10000000000000000uctk
$ shentud add-genesis-certifier $(shentud keys show jack -a)
$ shentud add-genesis-shield-admin $(shentud keys show jack -a)Notification: Every transaction will need 5000uctk , so you'd better start with more than 5000uctk here.
$ shentud gentx jack 10000000000000000uctk --chain-id shentuchain
$ shentud collect-gentxs
$ shentud start
$ shentud query account $(shentud keys show jack -a)
$ shentud keys add alice
$ shentud tx send jack $(shentud keys show alice -a) 7000000000uctk --gas-prices=0.025uctk --from jack --chain-id shentuchain
$ shentud query account $(shentud keys show jack -a)
$ shentud query account $(shentud keys show alice -a)We have a very simple storage setter / getter contract tests/sync/simple.sol.
pragma solidity >=0.4.0 <0.7.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}To deploy tests/sync/simple.sol contract (be sure to have solc installed), first compile it into a bytecode (.bin file) and abi.
Assuming you have simple.sol compiled into simple.bytecode (.bin file) and simple.abi
$ cd tests
$ shentud tx cvm deploy simple.bin --abi simple.abi --from node0Printed on the main terminal
Response:
TxHash: 8067DBC001BE239E5A44843CCEF4C71A87B802352989F97664AF8F265E7B888EPrinted on the shentud node server terminals
I[2019-06-27|09:05:33.281] CVM Start module=main txHash=8067dbc001be239e5a44843ccef4c71a87b802352989f97664af8f265e7b888e
I[2019-06-27|09:05:33.282] CVM module=main log_channel=Trace scope=NewVM message="(1) (89203146CD64A945BE5B02B0C44FB0040855C02A) 07BC7F3C21C34643A90AA1138C950FAC5025B693 (code=229) gas: 1000000 (d) 608060405234801561001057600080FD5B5060C68061001F6000396000F3FE6080604052348015600F57600080FD5B506004361060325760003560E01C806360FE47B11460375780636D4CE63C146062575B600080FD5B606060048036036020811015604B57600080FD5B8101908080359060200190929190505050607E565B005B60686088565B6040518082815260200191505060405180910390F35B8060008190555050565B6000805490509056FEA265627A7A723058205FEC64D09C278453AB74A855DCC214EA05BF9541E35E851AF41570397593055564736F6C63430005090032\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.283] CVM module=main log_channel=Trace scope=NewVM message="(pc) 0 (op) PUSH1 (st) 0 (gas) 1000000" tag=DebugOpcodes
I[2019-06-27|09:05:33.283] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000080\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.283] CVM module=main log_channel=Trace scope=NewVM message="(pc) 2 (op) PUSH1 (st) 1 (gas) 999999" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000040\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message="(pc) 4 (op) MSTORE (st) 2 (gas) 999998" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000080 @ 0x40\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message="(pc) 5 (op) CALLVALUE (st) 0 (gas) 999996" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message=" => 0\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message="(pc) 6 (op) DUP1 (st) 1 (gas) 999995" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message=" => [1] 0x0000000000000000000000000000000000000000000000000000000000000000\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.284] CVM module=main log_channel=Trace scope=NewVM message="(pc) 7 (op) ISZERO (st) 2 (gas) 999993" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message=" 0000000000000000000000000000000000000000000000000000000000000000 == 0 = 1\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 8 (op) PUSH2 (st) 2 (gas) 999991" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000010\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 11 (op) JUMPI (st) 3 (gas) 999990" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message=" ~> 16\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 16 (op) JUMPDEST (st) 1 (gas) 999988" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 17 (op) POP (st) 1 (gas) 999988" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000000\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 18 (op) PUSH1 (st) 0 (gas) 999987" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message=" => 0x00000000000000000000000000000000000000000000000000000000000000C6\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.285] CVM module=main log_channel=Trace scope=NewVM message="(pc) 20 (op) DUP1 (st) 1 (gas) 999986" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => [1] 0x00000000000000000000000000000000000000000000000000000000000000C6\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message="(pc) 21 (op) PUSH2 (st) 2 (gas) 999984" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => 0x000000000000000000000000000000000000000000000000000000000000001F\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message="(pc) 24 (op) PUSH1 (st) 3 (gas) 999983" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000000\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message="(pc) 26 (op) CODECOPY (st) 4 (gas) 999982" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => [0, 31, 198] 6080604052348015600F57600080FD5B506004361060325760003560E01C806360FE47B11460375780636D4CE63C146062575B600080FD5B606060048036036020811015604B57600080FD5B8101908080359060200190929190505050607E565B005B60686088565B6040518082815260200191505060405180910390F35B8060008190555050565B6000805490509056FEA265627A7A723058205FEC64D09C278453AB74A855DCC214EA05BF9541E35E851AF41570397593055564736F6C63430005090032\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message="(pc) 27 (op) PUSH1 (st) 1 (gas) 999979" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => 0x0000000000000000000000000000000000000000000000000000000000000000\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message="(pc) 29 (op) RETURN (st) 2 (gas) 999978" tag=DebugOpcodes
I[2019-06-27|09:05:33.286] CVM module=main log_channel=Trace scope=NewVM message=" => [0, 198] (198) 0x6080604052348015600F57600080FD5B506004361060325760003560E01C806360FE47B11460375780636D4CE63C146062575B600080FD5B606060048036036020811015604B57600080FD5B8101908080359060200190929190505050607E565B005B60686088565B6040518082815260200191505060405180910390F35B8060008190555050565B6000805490509056FEA265627A7A723058205FEC64D09C278453AB74A855DCC214EA05BF9541E35E851AF41570397593055564736F6C63430005090032\n" tag=DebugOpcodes
I[2019-06-27|09:05:33.287] CVM Stop module=main result=07bc7f3c21c34643a90aa1138c950fac5025b693To inspect deploy transaction details and to obtain Bech32 contract address
$ shentud query tx 8067DBC001BE239E5A44843CCEF4C71A87B802352989F97664AF8F265E7B888E
Response:
Height: 169
TxHash: 8067DBC001BE239E5A44843CCEF4C71A87B802352989F97664AF8F265E7B888E
Data: 07BC7F3C21C34643A90AA1138C950FAC5025B693
Raw Log: [{"msg_index":"0","success":true,"log":"shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we"}]
Logs: [{"msg_index":0,"success":true,"log":"shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we"}]
GasWanted: 200000
GasUsed: 41849
Tags:
- action = deploy
Timestamp: 2019-06-27T16:05:27ZTo inspect contract code bytes deployed at shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we
$ shentud query cvm code shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we
6080604052348015600F57600080FD5B506004361060325760003560E01C806360FE47B114603757
80636D4CE63C146062575B600080FD5B606060048036036020811015604B57600080FD5B81019080
80359060200190929190505050607E565B005B60686088565B604051808281526020019150506040
5180910390F35B8060008190555050565B6000805490509056FEA265627A7A723058205FEC64D09C
278453AB74A855DCC214EA05BF9541E35E851AF41570397593055564736F6C63430005090032To call SimpleStorage.set(123) at the contract
$ shentud tx cvm call shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we set 123 --from node0Then we can verify the storage setting by calling SimpleStorage.get() at the
contract
$ shentud tx cvm call shentu1q77870ppcdry82g25yfce9g043gztd5n99x7we get --from node0
Response:
TxHash: 6EAABFDF5022F21F88D9DBBE8A0837F3CF6819F06F801BEF301188F22DF16C9BWe can inspect and verify the read out value is indeed 123 (0x7b) by either looking at the shentud node server terminal
I[2019-06-27|09:20:44.674] CVM Stop module=main result=000000000000000000000000000000000000000000000000000000000000007bor query the get call transaction
$ shentud query tx 6EAABFDF5022F21F88D9DBBE8A0837F3CF6819F06F801BEF301188F22DF16C9B
Response:
Height: 333
TxHash: 6EAABFDF5022F21F88D9DBBE8A0837F3CF6819F06F801BEF301188F22DF16C9B
Data: 000000000000000000000000000000000000000000000000000000000000007B
Raw Log: [{"msg_index":"0","success":true,"log":""}]
Logs: [{"msg_index":0,"success":true,"log":""}]
GasWanted: 200000
GasUsed: 17677
Tags:
- action = call
Timestamp: 2019-06-27T16:20:38ZAnalogous to the steps above, a DeepSEA contract contract.ds can be deployed with:
$ shentud tx cvm deploy contract.ds --from node0Make sure that dsc (DeepSEA compiler) is in your PATH.
Start the rest-server in another terminal window:
$ shentud rest-server --trust-nodeBack to the previous terminal window where NODE0_KEY is defined:
# Initiate Transaction: Burn 2 ctk from node0.
$ curl -XPOST -s http://localhost:1317/ctk/burn --data-binary '{"base_req":{"from":"'$NODE0_KEY'","chain_id":"shentuchain"},"src":"'$NODE0_KEY'","amount":"2"}' > unsignedTx.json
# Sign Transaction
# Note: sequence and account-number can be found in account information
$ shentud tx sign unsignedTx.json --from $NODE0_KEY --offline --chain-id shentuchain --sequence 5 --account-number 0 > signedTx.json
# Broadcast Transaction
$ shentud tx broadcast signedTx.json
# Check the balance of node0
$ curl -s http:/localhost:1317/ctk/balance/$NODE0_KEY