阅读 1152

web3.js编译Solidity,发布,调用全部流程

原文链接: webfuse.cn

根据 web3.js编译Solidity,发布,调用全部流程(手把手教程)进行。因为这篇文章中的一些方法和最新版本的不一样了,中间遇到了一些坑,现把解决方法记录如下:

准备工作

安装 Node.js 、安装以太节点以及合约代码等与web3.js编译Solidity,发布,调用全部流程(手把手教程)中的一致。

  • 安装好的NodeJs版本为:v10.15.3
  • 安装好的以太节点版本为:ethereumjs-testrpc@6.0.3

遇到的坑

第一个坑:Solidity安装

按照官方文档使用 npm install -g solc 安装。

安装后验证版本应该使用 solcjs --version ,而不是 solc --version 。而且这边安装的是最新版本,也为后面的步骤埋下了坑。

第二个坑:TypeError: Cannot read property ‘solidity’ of undefined

使用以下代码:

let source = "pragma solidity ^0.4.0;contract Calc{  /*区块链存储*/  uint count;  /*执行会写入数据,所以需要`transaction`的方式执行。*/  function add(uint a, uint b) returns(uint){    count++;    return a + b;  }  /*执行不会写入数据,所以允许`call`的方式执行。*/  function getCount() returns (uint){    return count;  }}";
let calc = web3.eth.compile.solidity(source);复制代码

运行的时候报:

let calc = web3.eth.compile.solidity(source);
                            ^
TypeError: Cannot read property 'solidity' of undefined
    at Object.<anonymous> (/data/eth-contract/src/index.js:15:29)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)复制代码

这个是因为 Geth 在 1.5.9 版本以后就不支持此功能。见:Ethereum Dapp初心者之路(7): web3.eth.compile.solidity()替代方案

所以参考 ethereum.stackexchange.com/questions/6… 文章,将代码改为:

const fs = require("fs");
const solc = require('solc');
let source = fs.readFileSync('Calc.sol', 'UTF-8');
let compilationData = solc.compile(source);复制代码

第三个坑:编译报错

编译的时候,如果遇到以下报错:

{"errors":[{"component":"general","formattedMessage":"* Line 1, Column 1\n  Syntax error: value, object or array expected.\n* Line 1, Column 2\n  Extra non-whitespace after JSON value.\n","message":"* Line 1, Column 1\n  Syntax error: value, object or array expected.\n* Line 1, Column 2\n  Extra non-whitespace after JSON value.\n","severity":"error","type":"JSONError"}]}复制代码

这个是因为 solc 的版本不对,我们的代码中的版本是 ^0.4.0 ,而安装的 solc 的版本为 ^0.5.7 。应该用一样的版本。

代码中的版本改为^0.5.7,即pragma solidity ^0.5.7;。运行后,报:

assert.js:350
    throw err;
    ^
AssertionError [ERR_ASSERTION]: Invalid callback specified.
    at wrapCallback (/data/eth-contract/node_modules/solc/wrapper.js:16:5)
    at runWithReadCallback (/data/eth-contract/node_modules/solc/wrapper.js:42:26)
    at compileStandard (/data/eth-contract/node_modules/solc/wrapper.js:83:14)
    at Object.compileStandardWrapper (/data/eth-contract/node_modules/solc/wrapper.js:90:14)
    at Object.<anonymous> (/data/eth-contract/src/index.js:8:28)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)复制代码

参考 stackoverflow.com/questions/5… 后,如下操作:

npm uninstall -g solc
npm uninstall solc
npm install solc@0.4.25复制代码

然后将代码中的版本号改为:pragma solidity ^0.4.25;

完整源码

index.js:

const Web3 = require('web3');
const fs = require("fs");
const solc = require('solc');
let web3;
if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
} else {
    // set the provider you want from Web3.providers
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
//编译合约
let source = fs.readFileSync('Calc.sol', 'UTF-8').toString();
let calcCompiled = solc.compile(source);
//得到合约对象
let jsonInterface = calcCompiled['contracts'][':Calc']['interface'];
//获得abi
let abi = JSON.parse(jsonInterface);
//获取合约的代码
let bytecode = calcCompiled['contracts'][':Calc']['bytecode']
//得到合约对象
const calcContract = new web3.eth.Contract(abi,null,{
    data: '0x'+bytecode, 
    defaultGas:'4700000'
});
//部署者的地址,当前取默认账户的第一个地址
let deployeAddr = web3.eth.accounts[0];
//部署合约
calcContract.deploy().send({
    from: deployeAddr
})
.on('error', (error) => { 
    console.error(error)
 })
.on('transactionHash', (transactionHash) => { 
    console.log("transactionHash :" + transactionHash)
 })
.on('receipt', (receipt) => {
   console.log("receipt:") 
   console.log(receipt) 
})
.on('confirmation', (confirmationNumber, receipt) => { 
   console.log("confirmationNumber:"+confirmationNumber)
 }).then((newContractInstance) => {
    console.log(newContractInstance)
    console.log(newContractInstance.options.address) // instance with the new contract address
});复制代码

Calc.sol:

pragma solidity ^0.4.25;
contract Calc{
  /*区块链存储*/
  uint count;
  /*执行会写入数据,所以需要`transaction`的方式执行。*/
  function add(uint a, uint b) returns(uint){
    count++;
    return a + b;
  }
  /*执行不会写入数据,所以允许`call`的方式执行。*/
  function getCount() constant returns (uint){
    return count;
  }
}复制代码

package.json:

{
  "name": "eth-contract",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "solc": "^0.4.25",
    "web3": "^1.0.0-beta.52"
  }
}复制代码

参考

文章分类
开发工具
文章标签