乐趣区

关于区块链:如何在Conflux网络中使用jsconfluxsdk来构建一个简单的DApp

在这篇文章 / 教程中,我将展现如何应用 js-conflux-sdk 来构建一个简略的 DApp。

通过应用 js-conflux-sdk 这一基于 JavaScript 语言的集成开发库配合 npm 包治理,可能开发基于 Conflux 网络的 DApp,开发编译部署感兴趣的智能合约到 Conflux 网络中。心愿通过本文的记录与整顿,为更多对 Conflux 这一高性能公链感兴趣的同学们尝试应用 js-conflux-sdk 更加不便的开发本人所感兴趣的我的项目提供可能。

相较于 web3,js-conflux-sdk 对其逻辑进行了一系列改良与优化,本文将重点介绍应用该 SDK 开发调用相干智能合约的办法。如果您相熟编写智能合约的办法,可能利用智能合约做更多有意思的事件。

环境配置

首先您须要装置 nodejs 作为运行环境,参考文档实现对 nodejs 环境的部署操作。

  1. 抉择您心愿寄存 DAPP 的文件夹作为您的 工作目录
  2. 在工作目录下运行 npm 的 init 命令以创立 package.json 文件,该文件可能帮忙您存储项目名称、我的项目版本、我的项目形容、入口点文件、我的项目依赖信息等要害信息:

    npm init -y
  3. package.json 文件内容须要满足您的我的项目配置,此处为我创立的 DAPP 所对应的内容:
{
  "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"
}

此外须要通过 npm 包管理工具在我的项目门路下装置一些必要的依赖包,其命令如下:

npm install solc@0.5.11

通过 @操作符管制装置的版本,以确保编译器与咱们的代码兼容。

  1. 此外还须要通过 npm 命令在 同一工作目录 下装置 JavaScript Conflux Software Development Kit
npm install js-conflux-sdk

装置完后,您会发现在相应的目录下呈现了一个文件夹 node_modules,他是在装置 sdk 时主动生成的。

尝试开发

  1. 如果须要编写智能合约,咱们还须要尝试应用 Solidity 这门面向智能合约且为了实现智能合约而创立的高级编程语言开发智能合约。Solidity 文件的对应后缀为sol,为了不便进行开发,咱们在我的项目文件夹下创立了一个 contracts 文件夹。并将咱们编写的智能合约代码存入 ./contracts/test.sol 内,其内容如下:
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;
    }
}
  1. 尝试 Solidity 编程的形式能够是应用 Remix,能够通过将本人编写的 test.sol 文件上传至 Remix 进行编译,但咱们看到了另外一个有意思的办法(后续步骤有阐明),固此处截图仅为样例:

  1. 有位外国大佬,他编写了一份专门能够用于编译 sol 的 JS 脚本,其内容如下,咱们将它保留为 compile.js 并将咱们编写的 test.sol 文件放入 ./contracts/test.sol 下,同时将 compile.js 放在 ./ 下,这段代码的逻辑是读取 contracts 文件夹内合约并保留其 abi 和 bytecode 为 json 文件,存储到我的项目 ./build 文件夹下:
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');
}
  1. 通过在命令行运行 compile.js 编译 ./Contracts/test.sol
node compile.js

编译胜利状况下的运行后果如下:

  1. 能够看一下 ./build 文件夹内的数据,发现该编译工具生成了一个文件 ERC20.jsonSafeMath.json,其中 ERC20.json 的内容如下:
{
  "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"
}

这还没完,您须要在其中找到 bytecode 并将这一键对应的值前减少 0x,减少后的成果如下:

{
  "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"
}

为了不便大家比拟差别,只能把内容全副贴到这里,还请大家容纳了解,请您肯定要找到这个差别并在编译后增加 0x 否则,在后续部署合约时,会呈现谬误。abi 和 bytecode 都写在同一个 json 文件内的益处是,咱们只须要读取 ERC20.json 文件就能够应用它们调用 Conflux 创立智能合约

  1. 智能合约编译完了,咱们须要把它部署到 Conflux 网络中,还须要您花一些工夫做如下的筹备工作:
  2. 参考如何创立 Conflux 网页钱包创立属于您本人的 Conflux 钱包;
  3. 登录钱包后,点击页面中 申领测试币 按钮,申请 100CFX 测试币,后续部署合约须要进行生产;
  4. 点击左侧栏目中的 钱包私钥 获取您的私钥,这个私钥仅仅用于部署合约,不要通知他人,因为能够间接通过私钥进入到您的钱包,不能进行公开。
  5. 编写 deploy.js,其目标是将所写合约部署到 Conflux 网络,且部署的地位就是您填写私钥对应的合约地址(后续会有解说哦,不要焦急!)
// 填写您的私钥地址,为了缩小信息泄露,我应用的测试账户私钥后 20 位已应用星号进行代替解决,不要复制我的哈!const PRIVATE_KEY = '0x2772b19636f1d183a9a2a0d27da2a1d0efb97637b425********************';
// 合约地址
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));

须要阐明的是:nonce 是账户的交易序号每次一发动交易(包含部署合约)会应用一个 nonce 胜利后 nonce 自增 1,而如果交易执行不胜利时 nonce 不会自增 1(在这里指定了 nonce,您也能够把它删除以应用 Conflux 的默认值),再次部署的时候,因为零碎中已存在一个谬误而不能执行的 nonce,会报 nonce 已存在谬误运行成果如下图所示:

const config = require('./config.json'); 语句所读取的 config.json 文件内容如下所示,其中 private_key 应用与 deploy.js 雷同的私钥:

{
  "private_key": "2772b19636f1d183a9a2a0d27da2a1d0efb97637b425********************",
  "network": "homestead",
  "ERC20": "0x0DEd9F7D82a24099F09AF7831CaB61B31Df10487",
  "name": "Kanchan Coin",
  "symbol": "SNK",
  "total_supply": "1000000000000000000000000",
  "decimals": 18
}

部署与调用

  1. 运行 deploy.js 的办法如下:
node deploy.js <contract_name>

以咱们撰写的合约为例,办法如下:

node deploy.js ERC20

须要阐明的是 ERC20 是命令行参数,通过 deploy.js 内的代码 process.argv[2] 取得,帮忙咱们程序去 ./contracts/ 文件夹内寻找名为 test.json 并进行部署,其输入后果如下图所示:

  1. 通过程序回显 recv:0x846ba74923c670a5aec4e58b7551396b9bed5658 获取到了咱们部署合约的地址为 0x846ba74923c670a5aec4e58b7551396b9bed5658,应用该地址持续编写 call.js 代码,拜访并调用合约:
const {Conflux, util} = require('js-conflux-sdk');
// 合约持有者地址
const public_address = '0x17b38613e633c2b8fb4686a3a62b9b782ac5e0ca';
// 部署合约地址的地址,与 0x17b38613e633c2b8fb4686a3a62b9b782ac5e0ca 关联:下面曾经进行解释
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,
  });
  // 查看供给总量
  let result = await contract.totalSupply();
  console.log("Total supply:"  + result.toString());
  const account = cfx.Account(PRIVATE_KEY);
  
  // 查看账户余额
  let balance = await contract.balanceOf(public_address);
  console.log("address:"+public_address+"have balance:"+balance.toString());// 这是部署合约的账户公开地址
  
  // 尝试进行交易
  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);
  // 尝试进行转账操作
  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));
  1. 调用后果如下:

后记

  1. 通过上述环境配置这一波操作后,咱们的 package.json 文件内容也有所扭转:

    {
      "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"
      }
    }
  2. 我的项目的门路文件树如下所示:

    +Contract-project
     -call.js
     -compile.js
     -config.json
     -deploy.js
     +build
         -ERC20.json
         -SafeMath.json
     +contracts
         -test.sol
    -package.json
    -package-lock.json

感激社区小伙伴:余銘缘 的辛苦整顿~
鸣谢:刺客panpan 两位大佬的领导与帮忙。

退出移动版