pragma solidity >0.6.2 <0.7.0;
contract D {
uint public x;
constructor(uint a) public payable {
x = a;
}
}
contract C {
address[] public addresses;
address[] public predictedAddresses;
// D d = new D(4); // will be executed as part of C's constructor
function createD(uint arg) public {
D newD = new D(arg);
newD.x();
addresses.push(address(newD));
}
function createAndEndowD(uint arg, uint amount) public payable {
// Send ether along with the creation
D newD = new D{value: amount}(arg);
newD.x();
}
function createSalted(bytes32 salt, uint arg) public {
address predictedAddress = address(bytes20(keccak256(abi.encodePacked(
byte(0xff),
address(this),
salt,
keccak256(abi.encodePacked(
type(D).creationCode,
arg
))
))));
D d = new D{salt: salt}(arg);
require (address(d) == predictedAddress);
predictedAddresses.push(predictedAddress);
}
}无法在Remix上执行此事务,由于此错误而失败
transact to C.createSalted pending ...
[vm]from:0x7a0...9e160to:C.createSalted(bytes32,uint256) 0x9a6...ed3f2value:1332 weidata:0x611...00020logs:0hash:0x377...81188
transact to C.createSalted errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information. 发布于 2020-04-22 15:21:27
问题是从bytes32输出从keccak256转换到bytes20
address predictedAddress = address(bytes20(keccak256(...)));它保留了“最左边”的20个字节,而您想要的是“最右边”的20个字节。
可以通过将bytes32移至左12字节= 96位,然后再转换为bytes20来修复这个问题:
address predictedAddress = address(bytes20(keccak256(...) << 96));https://ethereum.stackexchange.com/questions/82693
复制相似问题