根据 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"
}
}