This site is in maintenance mode. Features may be unstable.
Warning! On-chain actions are not disabled.
Patract Labs' treasury report for Redspot v0.1
## Proposal overview Patract Labs ([https://patract.network\](https://patract.network)) provides solutions for Polkadot's parachain smart contract ecosystem. Three weeks ago, we applied a [treasury proposal](https://polkadot.polkassembly.io/motion/7) for Redspot v0.1. Here is a [youtube video](https://youtu.be/oPsD2W0mAQs) for overall demonstration. Now, we have finished all the features on time. We ask the councillors to check our work and give feedbacks. Welcome to our [riot room](https://app.element.io/#/room/!RZjiuwwssNFJZxaTjg:matrix.org) to talk about smart contract development. Redspot is inspired by Ethereum's Truffle. Redspot is a development environment, testing framework and asset pipeline for pallet-contracts. Redspot is trying to let the development of ink! be projectized and simplify the testing and interacting with contracts. The source code is in [https://github.com/patractlabs/redspot\](https://github.com/patractlabs/redspot). Jupiter is a long term Substrate testnet, dedicated in WASM smart contract development. We also host a public node in develop mode for deploying and testing smart contract. The source code is in [https://github.com/patractlabs/jupiter\](https://github.com/patractlabs/jupiter). ## Redspot v0.1 introduction Except the requirements in the proposal, **we have provided an objectified way to operate with contracts, which has not been implemented in Polkadot-js SDK yet**. For more information, please check out [contractApi](https://github.com/patractlabs/Redspot#contractapi). Most of the requirements are finished, expect some issues because ink! is a little unstable. Redspot's `migration` and `test` can be used just like web3.js. Developer can write scripts like this rather than using raw `call` to build raw extrinsic or RPC parameters. ```javascript // contractApi can be obtained by contract.load and contract.deployed, it can call the methods of the contract. // It calls the balanceOf method of the contract and returns the corresponding type by rpc. contractApi.messages.balanceOf(Alice.publicKey).call() // It sends a contract transfer to the chain and get a Result type. contractApi.messages.transfer(Bob.publicKey, '100000').send() ``` And then, We will show you the details about how Redspot works:  Currently, Redspot only support macOS and Linux, without Windows (waiting for ink! to support). ## Using Redspot on your computer Now, let's assume that you are a new developer for `pallet-contracts`. You know nothing about Substrate, hasn't prepared the developing environment for contracts. But, you had read some guides or cookbooks, and known a little about ink!. Then, you try to write WASM contracts for `pallet-contracts`. Just follow us to use Redspot and build your own contracts! 1. You **do not need to clone Redspot project**, just need to check whether there is a `npx` command on your machine. > `npx` is a package running tool that comes with `npm` 5.2+ and higher, it ensures that you always install the latest version. > > if you don't have `npx` command, just do `npm install -g npx` If you have installed `npx`, you must already have `npm`, or you could install `yarn` command, which is also what we recommend to use. 2. Install and use Redspot to pull a contract project template > npx redspot-new \ --template \ > `npx` would automatically download the newest `redspot-now` on your machine, and could use it in any place. So, you do not need to compile or build Redspot project. For example, if you want to create a contract project named `myerc20` and use the erc20 template as initial contract project framework, you could use the following command: ```bash npx redspot-new myerc20 --template erc20 ``` If you don't add `--template`, Redspot would use `flipper` as default template. Awesome, the `myerc20` is your own contract project, you could start developing contracts from now! ```bash $ npx Redspot-new myerc20 --template erc20 npx: installed 43 in 2.664s ✨ Creating a new Project in /myerc20. Installing packages. This might take a while. yarn add v1.22.5 info No lockfile found. [1/4] Resolving packages... # ... Done in 2.80s. 🎉 Success! Created myerc20 at /myerc20 👉 Inside that directory, you can run several commands to help you develop the contract: yarn build Compile the contract. yarn test Test the contract. yarn Migrate Migrate the contract ``` 3. Then, there is a template contract project in you current directory. The directory structure is similar with the directory that truffle generated, including `migartions`, `tests`, `Redspot-config.js` and so on. But currently, We can't support a `contracts` directory due to `ink!`'s limit. After `ink!` become stable in the future, we will move all the contracts into `contracts` directory and organise contracts. About more information, please refer to this [ink Issue](https://github.com/paritytech/cargo-contract/issues/60). Same with Truffle, the config file `Redspot-config.js` is the most important file in the project, which would let Redspot to identity the contract project. * If you want to know more about config file, please refer to [Project config](https://github.com/patractlabs/Redspot#project-config). * For the project structure, please refer to [Directory tree](https://github.com/patractlabs/Redspot#directory-tree). 4. Now, `lib.rs` is your contract file in your directory. This file will be changed in the future. You can just write you custom contract logic in it. For more information, please refer to `ink!`, and we advice new developers to look through all example in `ink!`. 5. Compile your contract! In the current directory, you could use those commands to compile you contract: ```bash npm run build # or yarn build ``` *That means you could use `npm run` or `yarn` to do the same operation. Later, we will use `yarn` to represent all cases for `npm run`* However you may haven't installed contract compile toolchain, then you would get: ```bash $ npm run build > [email protected] build /myerc20 > Redspot build /bin/sh: 1: cargo: not found ERROR: No `cargo-contract` found Run the following command to install it: $ cargo install --git https://github.com/paritytech/cargo-contract cargo-contract --force npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] build: `Redspot build` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] build script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2020-09-11T10_03_43_152Z-debug.log ``` Currently we just print some errors to advice developers to download toolchain, because `ink!` and `cargo-contract` is not stable now. In the future, we would automatically download all toolchains and install them, without bothering developers. After installing all toolchains, you could continue following steps. If compilation is done, you could get the artifacts in `artifacts` directory. ```bash $ yarn build yarn run v1.22.4 $ Redspot build ✨ Detect contracts: erc20(/.../.../myerc20/Cargo.toml) ===== Compile erc20 ===== cargo +nightly contract build [1/3] Building cargo project Compiling serde_derive v1.0.116 # ... Compiling erc20 v2.1.0 (/tmp/cargo-contract_OOAxF6) Finished release [optimized] target(s) in 14.86s [2/3] Post processing wasm file [3/3] Optimizing wasm file Original wasm size: 59.8K, Optimized: 37.6K Your contract is ready. You can find it here: /.../.../erc20/target/erc20.wasm ===== Generate metadata erc20 ===== cargo +nightly contract generate-metadata Generating metadata [1/3] Building cargo project Finished release [optimized] target(s) in 0.03s [2/3] Post processing wasm file [3/3] Optimizing wasm file Original wasm size: 59.8K, Optimized: 37.6K Updating git repository `https://github.com/paritytech/ink\` Updating crates.io index Compiling serde v1.0.116 # ... Compiling metadata-gen v0.1.0 (/tmp/cargo-contract_VQK5N3/.ink/metadata_gen) Finished release [optimized] target(s) in 21.21s Running `target/release/metadata-gen` Your metadata file is ready. You can find it here: /.../.../myerc20/target/metadata.json 🚚 Copy wasm files: erc20.wasm 🚚 Copy abi files: metadata.json 🎉 Compile successfully! You can find them at /.../.../myerc20/artifacts Done in 59.94s. ``` In our case, the `artifacts ` directory contains: ```bash artifacts |- erc20.json |- erc20.wasm ``` 6. Deploy your contracts. After development, it's time to deploy you contracts. **But before your deployment, please checkout `Redspot-config.js`**. ```javascript module.exports = { outDir: './artifacts', networks: { // this is the network config, same to truffle, the migaration/test command would connect network dependent on this config. development: { // `types` is related to connected chain, this is important for polkadot.js types: { Address: "AccountId", LookupSource: "AccountId", }, //`prefix` is the ss58check Version for chain address, this would affect the scripts in migrations/tests prefix: 42, endpoints: ['ws://127.0.0.1:9944'], // please check endpoints, it's the websocket address for blockchain // accounts is the key pair for migrations/tests accounts: [ { name: 'alice', publicKey: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', secretKey: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011', }, // ... ], }, }, }; ``` `networks` is as same as Truffle, will be used when set `--network` parameter for migaration/test commands. However, developers should be concerned with `types` and `prefix`. Those two parts are related to the connected blockchain. For example, If you want to connect with polkadot mainnet work, you should set `types` as `{}` and set `prefix` as `1` . If you want to connect with a custom Substrate blockchain, I should set `types` and `prefix` to matching value. For the types, please refer to [this link](https://polkadot.js.org/api/start/types.extend.html). We recommend developers to use "[Jupiter](https://github.com/patractlabs/jupiter)" as the testnet, because Jupiter contains a node in develop mode, which **doesn't need interval time to produce blocks.** This feature will save lot of time for developing contracts. > Note: if you use Jupiter as the testnet, please make sure the `types` is the correct json. If we assume the node is running on your machine, now you could deploy the myerc20 contract by doing `yarn migarate`: ```bash $ yarn migrate yarn run v1.22.4 $ Redspot migrate 👉 Running migration: 1_deploy_contracts.js ===== PutCode erc20 ===== WasmCode: 0x0061736d01000000015f1060027f7f......000006000000070041b080040b0102 ➤ erc20 codeHash: 0x9e05d9d5119b97343e69ed8ca68182639242c278ba04a753c36eeb44ba760fb1 ===== Instantiate erc20 ===== Endowment: 50000000000 GasRequired: 100000000000 CodeHash: 0x9e05d9d5119b97343e69ed8ca68182639242c278ba04a753c36eeb44ba760fb1 InputData: 80,65,230,145,252,0,0,100,167,179,182,224,13,0,0,0,0,0,0,0,0 ➤ erc20 contract address: 5D2z2wBACmwVCFBzSGjWbEhtQnxQuFiJNXoEJZeMyzeDd1rk Done in 1.73s. ``` Please notice that this command would automatically find the WASM file in `artifacts ` directory, find the deploy script in `migarations` directory, and executive it. The node where the WASM would be deployed is the `endpoint` in `Redspot-config.js` file. 7. Test your contracts. The most important thing in contract development is testing. `ink!` has already provided a way to write unit case to test contracts. However, simple unit test can't cover many complex situations, like multiple contracts project, the contracts related to block height, and so on. Thus, there must be a way for integration testing. `yarn test` is the command for contract integration test. It would execute all scripts in `tests` directory. Please notice that the default logic for contract address determiner is currently dependent on `code_hash`, `data_hash` and `origin` (refer to [`SimpleAddressDeterminer`](https://github.com/paritytech/substrate/blob/master/frame/contracts/src/lib.rs#L389)), so that **using same code and same init data from same sender** could only `instantiate` **once** for a contract, so that the testing scripts should be careful to handle `instantiate`(meaning deploy a contract) , like using different sender in different tests or using same deployed contract address when the contract could call more than once. Redspot hasn't implemented the same feature yet, which is like `migration.sol` in truffle, so Redspot can't automatically distinguish whether current contract has already been deployed. In the future, we would support this feature to help testing and instantiating (deploying). But now, if the tests are not complex, developers could start blockchain node using `--tmp` parameter. This parameter would start new chain without old data, thus developers could restart the blockchain node each time when they test. 8. objectified way to operate contracts Developer could use an objectified way to operate contracts in `migarate` and `test` scripts. In the future, this feature could be used in interactive console. Currently, we show an example like this: ```javascript // load contractApi from artifacts, this would auto parse information from contract abi file const erc20 = artifacts.require('erc20'); test('contract test', async () => { const Alice = config.pairs[0]; const Bob = config.pairs[1]; // call put_code in low level (note currently if upload same code would not cause extrinsic failed) const code_hash = await erc20.putCode(Alice); const erc20Api = await erc20.deployed( Alice, code_hash, erc20.abi.constructors[0]('1000000000000000016'), // instantiate parameters "50000000000", // endowment "100000000000" // gas limit ); // call rpc `call` to run contracts and get value const totalSupply = await erc20Api.messages.totalSupply().call(); // create an extrinsic and wait to block to pack and return the result of extrinsic result. const transferResult = await erc20Api.messages.transfer(Bob.publicKey, '100000').send({ from: Alice, gasLimit:"100000000000", }); } ``` From the example, we could see that developers do not need to care about how to parse ABI files and build call parameters, just operate a contract like an object. ## What we have done in this version As we described above, we have implemented all features required in the proposal. Except some issues due to the unstable `ink!`. Redspot could achieve a basic contract developing framework like how Truffle does in Ethereum. Maybe some features need to be improved. But currently, Redspot is a complete tool framework which could help developers to improve developing process for contracts. We hope all contract developers could benefit from Redspot! ## What features we will add in the next proposals We will apply a new detailed proposal for **Redspot v0.2**. Briefly, we will add a migrations framework to control whether a contracts has beed deployed. We will find a way to solve repeat instantiate and do not need to restart the blockchain. We will provide an interactive console for directly interact with contract. We will apply a new detailed proposal for **Europa v0.1** (firstly introduced in [Post #15](https://polkadot.polkassembly.io/post/15)). Europa is a sandbox of Substrate runtime environment, which would be used to simplify the developing, debugging, and integration test when developers develop Substrate runtime applications and test pallet-contracts. We will provide an independent runtime execution environment, allowing developers to use some special operation to operate the blockchain, like "jump to height" and "revert to height". We will provide an independent database for blockchain to establish other indexes, like index for extrinics. We will export stored key/value directly.
Comments