DAPP开发中趟过的坑

— 用时间砸出来的经验之谈 —
— 记录下来、造福后Zi人Ji —

issue & answer

TestRPC Runtime Error: out of gas

解决:别人的博客

truffle serve —— fsevents is not a constructor

解决:万能的Github

windows cmd 运行truffle命令与truffle.js冲突

放弃windows cmd,乱七八糟问题多,用 git bash

truffle-contract 链接 web3 1.0版本

解决:万能的Github-1
解决:万能的Github-2

最终解决代码如下:

1
2
3
4
5
6
7
8
//dirty hack for web3@1.0.0 support for localhost testrpc, see https://github.com/trufflesuite/truffle-contract/issues/56#issuecomment-331084530
if (typeof self.contract.currentProvider.sendAsync !== "function") {
self.contract.currentProvider.sendAsync = function() {
return self.contract.currentProvider.send.apply(
self.contract.currentProvider, arguments
);
};
}

metamask签名 智能合约中 验证签名 的坑

metamask中的web3 的 web3.eth.signweb3.personal.sign 两种签名方式用同一账户地址对于同一数据的签名结果是不同的(我也完全不知道为什么啊啊啊啊!)
然后智能合约中用ecrecover进行验证

web3.personal.sign(密文,签名地址,回调函数)

1
2
3
web3.personal.sign("0x19cdf95a071009070a345dd7ffd30ee7f18eee008f4f5d49945c1e2328c53e9d","0x18c61a12a369d91277ace3fd1c127a7f270d5d3b",console.log)
//err + result
// null "0x1ed1a91cfb8fb0fe77d63f2f6fbf12f789bdcf88c11f8e4ffc023f2fd61e7c264b1c59a79668eb698902d0043b9a0a3ee16165d3d57dc0a29dde61de8e8e687d1b"

web3.eth.sign(签名地址,密文,回调函数)

1
2
3
4
web3.eth.sign("0x18c61a12a369d91277ace3fd1c127a7f270d5d3b",
"0x19cdf95a071009070a345dd7ffd30ee7f18eee008f4f5d49945c1e2328c53e9d",console.log)
//err + result
// null "0x541959986ccc60b5a5ba5bf90535b5e1d372972413306df4d67c6224f79e585e4ff598da3c700965a70ff204ded769b3261ff67214b2d4fa955ee3dbaad76a301b"

js中进行分解signature

1
2
3
4
var signature = req.query.signature.slice(2,132) //去除0x
var r = "0x"+signature.slice(0,64);
var s = "0x"+signature.slice(64,128);
var v = parseInt(signature.slice(128,130),16); //转为int形式 ,此处产生的v 直接就为27或28

智能合约中的ecrecover

1
2
//uint8 v, bytes32 r, bytes32 s
address addr = ecrecover(hashOfMsg, v, r, s);

关键的来了!
智能合约中的ecrecover是识别metamask中的web3.eth.sign
而不识别web3.personal.sign!!!!!!!!!!!!
不识别的意思是验证时,结果不一样!

结论:智能合约中的ecrecover是识别metamask中的web3.eth.sign


2018.12.12更新:
今天有个老哥找到我问了web3.personal.sign该如何解密。
当初是绕过了这个问题,没有继续研究了,讨论了下,这个签名与验证用在一些dapp的快速登录中,形成的登录效果极其方便。
这里找到了网上用js做前端后端实现使用metamask快速登录的例子,在后端验证时是调用的eth-sig-util库的recoverPersonalSignature (msgParams)(当然并不是在智能合约中解决了web3.personal.sign的验证问题)
留个储备链接以防以后需要:
en原文
译文
demo-github地址
eth-sig-util包

那位老哥找到了如何解密的办法:源码如下:
personal.sign():

eth.sign()

智能合约与JS中的sha256

当在在智能合约中用到的ecrecover(hashOfMsg, v, r, s)

智能合约中的sha256(address)。address是作为bytes进行sha256;
在js中的sha256("0x123")是作为字符串形式进行sha256。

两者的结果不同,如果需要相同,需要在js中修改"0x123"为bytes形式进行sha256

truffle寻找合约地址

如何在truffle中找到部署合约的合约地址?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var Web3 = require('web3');
var contract = require('truffle-contract');
//引入合约 以及 配置
var ConContract = require('../../contracts/Coin.json');
//链接到以太坊节点
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
const Cont = {
//地址
contract: null,
//合约
instance: null,

//初始化链接到以太坊节点
init: function () {
let self = this

return new Promise(function (resolve, reject) {
self.contract = contract(ConContract)
self.contract.setProvider(web3.currentProvider)
self.contract.deployed().then(instance => {
self.instance = instance
resolve()
}).catch(err => {
reject(err)
})
})
}
}
module.exports = Cont;

如此初始化合约,合约地址在Cont.instance.address