我有一个合同,代表地址持有令牌,并在提供已签名的转移哈希值时将其转移。
合同看起来像这样
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
contract Settlement is Ownable {
using SafeMath for uint256;
struct Withdrawal {
uint256 amount;
address token;
uint256 timestamp;
}
// token => (holder => balance)
mapping(address => mapping(address => uint256)) public tokenBalances;
mapping(address => Withdrawal) withdrawals;
function transferInto(address recipient, uint256 amount, address token) public {
//get the tokens
IERC20(token).transferFrom(msg.sender, address(this), amount);
//increase the token balance in the payment contract
tokenBalances[token][recipient] = tokenBalances[token][recipient].add(amount);
}
string constant private prefix = "\u0019Ethereum Signed Message:\n32";
function transfer(address to, uint256 amount, address token, uint8 v, bytes32 r, bytes32 s)
public {
bytes32 paramHash = keccak256(abi.encodePacked(to, amount, token));
address signer = ecrecover(keccak256(abi.encodePacked(prefix, paramHash)), v, r, s);
//SafeMath ensures that the signer has enough tokens in their payment account
tokenBalances[token][signer] = tokenBalances[token][signer].sub(amount);
IERC20(token).transfer(to, amount);
}
}
并且我编写了一个函数来创建签名,该签名将传递给合同的transfer
函数:
const ethers = require('ethers')
const BigNumber = require('bignumber.js')
const utils = require('web3-utils')
// the purpose of this function is to be able to create BN from exponent numbers like '2e22' they must be formatted as string in this case
const toBN = (num) => utils.toBN(new BigNumber(num).toString(10))
async function signTransfer(recipient, amount, tokenAddress, privateKey){
const wallet = new ethers.Wallet(privateKey)
const txMsg = utils.soliditySha3(recipient, toBN(amount), tokenAddress)
const messageHashBytes = ethers.utils.arrayify(txMsg)
const flatSig = await wallet.signMessage(messageHashBytes)
const sig = ethers.utils.splitSignature(flatSig)
return {
...sig,
hash: messageHashBytes
}
}
module.exports = signTransfer
这可行,但是我必须同时使用ethers
和web3-utils
软件包来实现此目的。
如何用soliditySha3
版本替换ethers
函数?
我看了soliditySha3
的实现,看起来很复杂。
问题是web3js
似乎没有在我的函数中创建messageHashBytes
的函数。所以我都坚持。并不是很糟糕,但是减少库的数量会很好。
答案 0 :(得分:0)
如果可以使用web3.js进行所有操作,那么应该可以使用以下方法:
function signTransfer(recipient, amount, tokenAddress, privateKey) {
return web3.eth.accounts.sign(
web3.utils.soliditySha3(recipient, toBN(amount), tokenAddress),
privateKey);
}