Ethereum合约开发若干问题
- 1. 文档更新说明
- 2. 前言
- 3. 问题
- 3.0.1. 基于以太坊技术的智能合约ERC20的合约代码要注意哪些常见的代码安全,合约代码会有哪些常见的BUG和安全漏洞
- 3.0.2. 怎么降低矿工费,有什么好方案可以避免因矿工费问题偶尔导致交易失败的问题
- 3.0.3. Web3j代码调用合约的转移方法时,偶尔没有返回交易号,那我们怎么判断该交易是要成功还是失败,我们的业务会受影响,如何解决这个问题
- 3.0.4. Web3j代码通过交易号查询出来的交易凭证信息的方法里,有返回交易的很多信息,但是没有返回时间戳,也无法知道token
- 3.0.5. Thansfer的信息,不知道转移给哪个地址,转移了多少token,不知道有没有什么代码可以获取这些交易信息
- 3.0.6. 如何保证合约安全,如何保证交易稳定,交易延迟问题,交易失败问题,有没有一套比较好的方案,保证业务不受区块链的影响或者补偿机制
文档更新说明
- 最后更新 2018年06月27日
- 首次更新 2018年06月27日
前言
解答新手若干问题.(其实大家都是新手, 都是随时成为先烈的人😉)
问题
基于以太坊技术的智能合约ERC20的合约代码要注意哪些常见的代码安全,合约代码会有哪些常见的BUG和安全漏洞
ERC20合约主要用户数字资产管理, 常见的攻击方式有溢出攻击如下:
- 溢出攻击(Over and under flows), 近期爆出的合约漏洞基本都是没有处理溢出问题. 可使用safemath库做四则运算解决这个问题.
- 可重入性, 这个攻击方式应该是编程严谨性问题.近期也有项目合约出现这个漏洞. 解决方案简单说就是在给他人转账之前, 一定要先把余额扣除, 再转账.
- 可见性攻击, 当涉及到权限问题的时候, 要注意做好控制,防止攻击者夺得合约的最高权限(owner)从而导致合约作废.
怎么降低矿工费,有什么好方案可以避免因矿工费问题偶尔导致交易失败的问题
降低矿工费嘛, 可以看看全球用户活跃时间段是什么时候,然后避开这个时间.除此之外没有其他办法了据我所知. 矿工费最好是设计成动态值, GETH本身是支持动态设置GAS的, 或者可以使用**https://etherscan.io/**上的一个API,得到当前时间段合适的GAS值.
Web3j代码调用合约的转移方法时,偶尔没有返回交易号,那我们怎么判断该交易是要成功还是失败,我们的业务会受影响,如何解决这个问题
暂时没有遇到这个问题, 如果没有返回hash值, 一般是节点的交易池满了导致的,但是按理说代码会报错才是.可以看看代码是否已经报错了然后开发者没有主动去接收.
Web3j代码通过交易号查询出来的交易凭证信息的方法里,有返回交易的很多信息,但是没有返回时间戳,也无法知道token
交易被receipt之后,可以通过
web3.eth.getTransactionReceipt("0xc79d3fe545c03a32a7bf85a02461101fc06423c6ae0fc1ee698149b5ec381b97").then(console.log)
得到交易被打包的块, 再通过
web3.eth.getBlock(2504695).then(console.log)
得到具体打包的block, block里面会包含时间戳的. 至于说无法知道是哪个token, 这个应该是开发者没有看清楚吧, 一直都是有的.下面我展示一个完整的receipt结构, 里面的logs.address就是事件发生时候的合约地址.(下面例子是我近期开发的一个世界杯ERC721合约, 里面涵盖操作ERC721和ERC20的log)
1 | { |
Thansfer的信息,不知道转移给哪个地址,转移了多少token,不知道有没有什么代码可以获取这些交易信息
没看懂这个问题. 如果是ERC20的transfer, 是可以从log中得到所有相关信息的.
如何保证合约安全,如何保证交易稳定,交易延迟问题,交易失败问题,有没有一套比较好的方案,保证业务不受区块链的影响或者补偿机制
合约只保留必备的功能, 减少代码复杂度. 少用循环语句. 交易失败一般是因为给出的手续费太少, 另外一个因素就是合约的代码执行复杂度会随着存储数据的增加而变得复杂, 当循环次数到达一定次数之后, 可能会导致合约被卡住了无法继续执行了.
另外一个因素就是要尽量降低Gas的消耗.比如多使用view关键字,这样外部执行函数就完全免费了.使用结构体封装方式,封装整形,比如int8,int32等,也可以节省Gas的消耗;而单独定义变量int8和int256两者消耗的gas是相同的.