In this article / tutorial, I'll show you how to use js-conflux-sdk To build a simple DApp.
through the use of js-conflux-sdk This integrated development library based on JavaScript language, combined with npm package management, can develop DApp based on Conflux network, develop, compile and deploy interested smart contracts to Conflux network. It is hoped that through the recording and collation of this article, it will provide the possibility for more students interested in the high-performance public chain to try to use js Conflux SDK to develop the projects they are interested in more conveniently.
Compared to web3 , JS conflux SDK has made a series of improvements and optimizations to its logic. This paper will focus on the method of using the SDK to develop and call relevant smart contracts. If you are familiar with the method of writing smart contracts, you can do more interesting things with smart contracts.
Environment configuration
First, you need to install nodejs as the running environment. Refer to file Complete the deployment of nodejs environment.
- Select the folder where you want to store DAPP as your working directory.
Run the init command of npm in the working directory to create the package JSON file, which can help you store key information such as project name, project version, project description, entry point file and project dependency information:
npm init -y
- package. The content of the JSON file needs to meet your project configuration. Here is the content corresponding to the DAPP I created:
{ "name": "contract-project", "version": "1.0.0", "description": "smart Contract", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Yumingyuan", "license": "ISC" }
In addition, you need to install some necessary dependent packages under the project path through the npm package management tool. The commands are as follows:
npm install solc@0.5.11
Control the installed version through the @ operator to ensure that the compiler is compatible with our code.
- In addition, you need to install the JavaScript flux software development kit in the same working directory through the npm command
npm install js-conflux-sdk
After installation, you will find a folder node in the corresponding directory_ Modules, which is generated automatically when the sdk is installed.
Try to develop
- If we need to write a smart contract, we also need to try to use it Solidity This aspect is to develop smart contracts with high-level programming languages created to implement smart contracts. The corresponding suffix of the solid file is sol. In order to facilitate development, we have created a contracts folder under the project folder. And save the smart contract code we wrote into/ contracts/test. In sol, the contents are as follows:
pragma solidity ^0.5.0; contract ERC20 { using SafeMath for uint256; event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens); mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed; string public symbol; uint8 public decimals; string public name; uint256 private _totalSupply; constructor(uint8 _decimals, string memory _symbol, string memory _name, uint256 _total_supply) public{ decimals = _decimals; symbol = _symbol; name = _name; _totalSupply = _total_supply; balances[msg.sender] = _totalSupply; } function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address tokenOwner) public view returns (uint) { return balances[tokenOwner]; } function transfer(address receiver, uint numTokens) public returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); emit Transfer(msg.sender, receiver, numTokens); return true; } function approve(address delegate, uint numTokens) public returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; } function allowance(address owner, address delegate) public view returns (uint) { return allowed[owner][delegate]; } function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner].sub(numTokens); allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens); balances[buyer] = balances[buyer].add(numTokens); emit Transfer(owner, buyer, numTokens); return true; } } library SafeMath { function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } }
- The way to try solid programming can be to use Remix , you can write your own test The sol file is uploaded to Remix for compilation, but we see another interesting method (described in the next steps). The screenshot here is only an example:
- A foreigner wrote a JS script that can be used to compile sol. The content is as follows. We save it as compile JS and put the test Sol file into/ contracts/test.sol, and compile JS on/ The logic of this code is to read the contract in the contracts folder, save its abi and bytecode as json files, and store them in the project/ Under the build folder:
const path = require('path'); const fs = require('fs-extra'); const solc = require('solc'); const sourceFolderPath = path.resolve(__dirname, 'contracts'); const buildFolderPath = path.resolve(__dirname, 'build'); const getContractSource = contractFileName => { const contractPath = path.resolve(__dirname, 'contracts', contractFileName); return fs.readFileSync(contractPath, 'utf8'); }; let sources = {}; var walk = function (dir) { var results = []; var list = fs.readdirSync(dir); list.forEach(function (file) { file = dir + '/' + file; var stat = fs.statSync(file); if (stat && stat.isDirectory()) { results = results.concat(walk(file)); } else { if (file.substr(file.length - 4, file.length) === ".sol") { sources = { ...sources, [file]: { content: getContractSource(file) } }; } results.push(file); } }); return results; }; walk(sourceFolderPath); const input = { language: 'Solidity', sources, settings: { outputSelection: { '*': { '*': ['*'] } } } } console.log('\nCompiling contracts...'); const output = JSON.parse(solc.compile(JSON.stringify(input))); console.log('Done'); let shouldBuild = true; if (output.errors) { console.error(output.errors); // throw '\nError in compilation please check the contract\n'; for (error of output.errors) { if (error.severity === 'error') { shouldBuild = false; throw 'Error found'; break; } } } if (shouldBuild) { console.log('\nBuilding please wait...'); fs.removeSync(buildFolderPath); fs.ensureDirSync(buildFolderPath); for (let contractFile in output.contracts) { for (let key in output.contracts[contractFile]) { fs.outputJsonSync( path.resolve(buildFolderPath, `${key}.json`), { abi: output.contracts[contractFile][key]["abi"], bytecode: output.contracts[contractFile][key]["evm"]["bytecode"]["object"] }, { spaces: 2, EOL: "\n" } ); } } console.log('Build finished successfully!\n'); } else { console.log('\nBuild failed\n'); }
- By running compile. On the command line JS compilation/ Contracts/test.sol :
node compile.js
The running results when the compilation is successful are as follows:
- You can have a look/ According to the data in the build folder, it is found that the compiler tool has generated a file erc20 JSON and safemath JSON, where erc20 JSON is as follows:
{ "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "delegate", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "buyer", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "internalType": "address", "name": "tokenOwner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "delegate", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint8", "name": "_decimals", "type": "uint8" }, { "internalType": "string", "name": "_symbol", "type": "string" }, { "internalType": "string", "name": "_name", "type": "string" }, { "internalType": "uint256", "name": "_total_supply", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "tokenOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokens", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokens", "type": "uint256" } ], "name": "Transfer", "type": "event" } ], "bytecode": "60806040523480156200001157600080fd5b506040516200100f3803806200100f833981810160405260808110156200003757600080fd5b8101908080519060200190929190805160405193929190846401000000008211156200006257600080fd5b838201915060208201858111156200007957600080fd5b82518660018202830111640100000000821117156200009757600080fd5b8083526020830192505050908051906020019080838360005b83811015620000cd578082015181840152602081019050620000b0565b50505050905090810190601f168015620000fb5780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b506040526020018051906020019092919050505083600360006101000a81548160ff021916908360ff1602179055508260029080519060200190620001ff9291906200026f565b508160049080519060200190620002189291906200026f565b50806005819055506005546000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050506200031e565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002b257805160ff1916838001178555620002e3565b82800160010185558215620002e3579182015b82811115620002e2578251825591602001919060010190620002c5565b5b509050620002f29190620002f6565b5090565b6200031b91905b8082111562000317576000816000905550600101620002fd565b5090565b90565b610ce1806200032e6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461022557806370a082311461024957806395d89b41146102a1578063a9059cbb14610324578063dd62ed3e1461038a57610093565b806306fdde0314610098578063095ea7b31461011b57806318160ddd1461018157806323b872dd1461019f575b600080fd5b6100a0610402565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100e05780820151818401526020810190506100c5565b50505050905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101676004803603604081101561013157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104a0565b604051808215151515815260200191505060405180910390f35b610189610592565b6040518082815260200191505060405180910390f35b61020b600480360360608110156101b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061059c565b604051808215151515815260200191505060405180910390f35b61022d610917565b604051808260ff1660ff16815260200191505060405180910390f35b61028b6004803603602081101561025f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061092a565b6040518082815260200191505060405180910390f35b6102a9610972565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102e95780820151818401526020810190506102ce565b50505050905090810190601f1680156103165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103706004803603604081101561033a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a10565b604051808215151515815260200191505060405180910390f35b6103ec600480360360408110156103a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf2565b6040518082815260200191505060405180910390f35b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104985780601f1061046d57610100808354040283529160200191610498565b820191906000526020600020905b81548152906001019060200180831161047b57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600554905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211156105e957600080fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111561067257600080fd5b6106c3826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061079482600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610865826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9090919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b600360009054906101000a900460ff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a085780601f106109dd57610100808354040283529160200191610a08565b820191906000526020600020905b8154815290600101906020018083116109eb57829003601f168201915b505050505081565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610a5d57600080fd5b610aae826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b41826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9090919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600082821115610c8557fe5b818303905092915050565b600080828401905083811015610ca257fe5b809150509291505056fea265627a7a72315820b72443db895a78ba6a5792887a143c1eef3b80737abde5b746129f115dbde05164736f6c634300050b0032" }
This is not over yet. You need to find bytecode in it and increase the value corresponding to this key by 0x. The effect is as follows:
{ "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "delegate", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "buyer", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "internalType": "address", "name": "tokenOwner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "uint256", "name": "numTokens", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "delegate", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint8", "name": "_decimals", "type": "uint8" }, { "internalType": "string", "name": "_symbol", "type": "string" }, { "internalType": "string", "name": "_name", "type": "string" }, { "internalType": "uint256", "name": "_total_supply", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "tokenOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokens", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokens", "type": "uint256" } ], "name": "Transfer", "type": "event" } ], "bytecode": "0x60806040523480156200001157600080fd5b506040516200100f3803806200100f833981810160405260808110156200003757600080fd5b8101908080519060200190929190805160405193929190846401000000008211156200006257600080fd5b838201915060208201858111156200007957600080fd5b82518660018202830111640100000000821117156200009757600080fd5b8083526020830192505050908051906020019080838360005b83811015620000cd578082015181840152602081019050620000b0565b50505050905090810190601f168015620000fb5780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b506040526020018051906020019092919050505083600360006101000a81548160ff021916908360ff1602179055508260029080519060200190620001ff9291906200026f565b508160049080519060200190620002189291906200026f565b50806005819055506005546000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050506200031e565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002b257805160ff1916838001178555620002e3565b82800160010185558215620002e3579182015b82811115620002e2578251825591602001919060010190620002c5565b5b509050620002f29190620002f6565b5090565b6200031b91905b8082111562000317576000816000905550600101620002fd565b5090565b90565b610ce1806200032e6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461022557806370a082311461024957806395d89b41146102a1578063a9059cbb14610324578063dd62ed3e1461038a57610093565b806306fdde0314610098578063095ea7b31461011b57806318160ddd1461018157806323b872dd1461019f575b600080fd5b6100a0610402565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100e05780820151818401526020810190506100c5565b50505050905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101676004803603604081101561013157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104a0565b604051808215151515815260200191505060405180910390f35b610189610592565b6040518082815260200191505060405180910390f35b61020b600480360360608110156101b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061059c565b604051808215151515815260200191505060405180910390f35b61022d610917565b604051808260ff1660ff16815260200191505060405180910390f35b61028b6004803603602081101561025f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061092a565b6040518082815260200191505060405180910390f35b6102a9610972565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102e95780820151818401526020810190506102ce565b50505050905090810190601f1680156103165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103706004803603604081101561033a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a10565b604051808215151515815260200191505060405180910390f35b6103ec600480360360408110156103a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf2565b6040518082815260200191505060405180910390f35b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104985780601f1061046d57610100808354040283529160200191610498565b820191906000526020600020905b81548152906001019060200180831161047b57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600554905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211156105e957600080fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111561067257600080fd5b6106c3826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061079482600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610865826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9090919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b600360009054906101000a900460ff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a085780601f106109dd57610100808354040283529160200191610a08565b820191906000526020600020905b8154815290600101906020018083116109eb57829003601f168201915b505050505081565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610a5d57600080fd5b610aae826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b41826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9090919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600082821115610c8557fe5b818303905092915050565b600080828401905083811015610ca257fe5b809150509291505056fea265627a7a72315820b72443db895a78ba6a5792887a143c1eef3b80737abde5b746129f115dbde05164736f6c634300050b0032" }
In order to facilitate you to compare the differences, you can only post all the contents here. Please be tolerant and understand. Please be sure to find the difference and add 0x after compilation. Otherwise, errors will occur during subsequent deployment of the contract. The advantage of both abi and bytecode being written in the same json file is that we only need to read erc20 json files can be used to call Conflux to create smart contracts.
- After the smart contract is compiled, we need to deploy it to the Conflux network. You also need to take some time to do the following preparations:
- reference resources How to create Conflux web Wallet Create your own Conflux wallet;
- After logging in the wallet, click the apply for test currency button on the page to apply for 100CFX test currency. Subsequent deployment contracts need to be consumed;
- Click the wallet private key in the left column to obtain your private key. This private key is only used to deploy the contract. Don't tell others, because you can enter your wallet directly through the private key and can't make it public.
- Write deploy JS, the purpose is to deploy the written contract to the Conflux network, and the deployment location is the contract address corresponding to the private key (it will be explained later, don't worry!)
// Fill in your private key address. In order to reduce information disclosure, the last 20 digits of the private key of my test account have been replaced with an asterisk. Don't copy my ha! const PRIVATE_KEY = '0x2772b19636f1d183a9a2a0d27da2a1d0efb97637b425********************'; // Contract address const CONTRACT = ''; const { Conflux } = require('js-conflux-sdk'); const compiled = require(`./build/${process.argv[2]}.json`); const config = require('./config.json'); async function main() { const cfx = new Conflux({ url: 'http://main.confluxrpc.org', }); const account = cfx.Account(PRIVATE_KEY); // create account instance console.log(account.address); // create contract instance const contract = cfx.Contract({ abi: compiled.abi, bytecode: compiled.bytecode, }); //console.log(contract.address) const receipt = await contract.constructor(config["decimals"], config["symbol"], config["name"], config["total_supply"]) .sendTransaction({ from: account }) .confirmed(); console.log("recv:"+receipt.contractCreated); } main().catch(e => console.error(e));
It should be noted that nonce is the transaction serial number of the account. One nonce will be used every time a transaction is initiated (including the deployment contract). Nonce will increase by 1 automatically after successful execution. If the transaction is not executed successfully, nonce will not increase by 1 automatically (nonce is specified here, and you can also delete it to use the default value of Conflux). When deploying again, nonce that cannot be executed because there is an error in the system will report that nonce has an error. The operation effect is shown in the following figure:
const config = require('./config.json'); Config. Read by statement The contents of the JSON file are as follows, where private_ Use key with deploy JS same private key:
{ "private_key": "2772b19636f1d183a9a2a0d27da2a1d0efb97637b425********************", "network": "homestead", "ERC20": "0x0DEd9F7D82a24099F09AF7831CaB61B31Df10487", "name": "Kanchan Coin", "symbol": "SNK", "total_supply": "1000000000000000000000000", "decimals": 18 }
Deployment and invocation
- Run deploy JS is as follows:
node deploy.js <contract_name>
Taking the contract we wrote as an example, the method is as follows:
node deploy.js ERC20
It should be noted that ERC20 is a command-line parameter through deploy JS Argv [2] get, help our program go/ Find the folder named test in the contracts / folder JSON and deploy it. The output results are shown in the following figure:
- Through the program echo recv:0x846ba74923c670a5aec4e58b7551396b9bed5658, we obtained that the address of our deployment contract is 0x846ba74923c670a5aec4e58b7551396b9bed5658. Continue to write call using this address JS code, access and call the contract:
const { Conflux, util } = require('js-conflux-sdk'); //Address of contract holder const public_address = '0x17b38613e633c2b8fb4686a3a62b9b782ac5e0ca'; // The address of the deployment contract address is associated with 0x17b38613e633c2b8fb4686a3a62b9b782ac5e0ca: as explained above const contractAddress = '0x846ba74923c670a5aec4e58b7551396b9bed5658'; const PRIVATE_KEY = '0x2772b19636f1d183a9a2a0d27da2a1d0efb97637b425********************'; const compiled = require(`./build/ERC20.json`) async function main() { const cfx = new Conflux({ url: 'http://main.confluxrpc.org', }); const contract = cfx.Contract({ address : contractAddress, abi: compiled.abi, }); // View total supply let result = await contract.totalSupply(); console.log("Total supply:" + result.toString()); const account = cfx.Account(PRIVATE_KEY); //View account balance let balance = await contract.balanceOf(public_address); console.log("address:"+public_address+" have balance:"+balance.toString());//This is the public address of the account for the deployment contract //Attempt to trade let allowance_result=await contract.allowance(public_address,'0x1941E3137aDDf02514cBFeC292710463d41e8196'); console.log("tx:"+allowance_result); approve_result=await contract.approve(transfer_address,1000); console.log("approve result:"+approve_result); //Attempt transfer operation let transfer_balance=await contract.balanceOf(transfer_address); console.log("address:"+transfer_address+" have balance:"+transfer_balance.toString()); await contract.transfer(transfer_address,100).sendTransaction({ from: account }).confirmed(); let transfer_balance_after=await contract.balanceOf(transfer_address); console.log("after transfer address:"+transfer_address+" have balance:"+transfer_balance_after.toString()); } main().catch(e => console.error(e));
- The call result is as follows:
Postscript
After the above environment configuration, our package The JSON file content has also changed:
{ "name": "contract-project", "version": "1.0.0", "description": "smart Contract", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Yumingyuan", "license": "ISC", "dependencies": { "ethers": "^5.0.3", "fs-extra": "^9.0.1", "js-conflux-sdk": "^0.10.3", "solc": "^0.5.11" } }
The path file tree of the project is as follows:
+Contract-project -call.js -compile.js -config.json -deploy.js +build -ERC20.json -SafeMath.json +contracts -test.sol -package.json -package-lock.json
Thanks to the community partners: Yu Mingyuan's hard work ~
Thanks: the guidance and help of Assassin and panpan.