使用合约管理钱包
代码备份
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "@openzeppelin/contracts@4.4.0/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts@4.4.0/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts@4.4.0/access/Ownable.sol";
interface IWallet{
function tokenTransfer(address token,address reciever,uint256 amount) external;
}
contract Wallet is Ownable {
constructor(address _owner) {
}
function tokenTransfer(address token,address reciever,uint256 amount) external onlyOwner{
SafeERC20.safeTransfer(IERC20(token),reciever,amount);
}
}
contract WalletFactory is Ownable{
mapping(uint256 => address)public wallets;
function deploy(
uint256 _salt
) external onlyOwner returns (address) {
wallets[_salt] = address(new Wallet{salt: bytes32(_salt)}(address(this)));
return wallets[_salt];
}
function getBytecode()
internal
view
returns (bytes memory)
{
bytes memory bytecode = type(Wallet).creationCode;
return abi.encodePacked(bytecode, abi.encode(address(this)));
}
function getAddress(uint256 _salt)
public
view
returns (address)
{
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff), // 0
address(this), // address of factory contract
_salt, // a random salt
keccak256(getBytecode()) // the wallet contract bytecode
)
);
// Cast last 20 bytes of hash to address
return address(uint160(uint256(hash)));
}
function tokenTransfer(address token,address sender,address receiver,uint256 amount) external onlyOwner{
IWallet(sender).tokenTransfer(token,receiver,amount);
}
function flushs(address token,address[] memory _accounts,address receiver)public onlyOwner{
for(uint256 i=0;i<_accounts.length;i++){
uint256 balance = IERC20(token).balanceOf(_accounts[i]);
if(balance>0){
IWallet(_accounts[i]).tokenTransfer(token,receiver,balance);
}
}
}
}
链下计算地址
// genAddress 使用salt生成地址,算法与合约保持一致
func (svc *Service) genAddress(_salt int64) (common.Address, error) {
cfg := svc.cfg.Chain
creationCode, err := hexutil.Decode(cfg.CreationCode)
if err != nil {
return common.Address{}, errors.Wrap(err, "Bad CreationCode")
}
contract := common.HexToAddress(cfg.WalletFactory).Bytes()
byteCodeHash := crypto.Keccak256Hash(
creationCode,
common.LeftPadBytes(contract, 32),
)
salt := big.NewInt(_salt)
hash := crypto.Keccak256Hash(
[]byte{0xff},
contract,
common.LeftPadBytes(salt.Bytes(), 32),
byteCodeHash.Bytes(),
)
var address common.Address
copy(address[:], hash.Bytes()[12:])
return address, err
}
posted on 2022-12-15 15:14 angry-baby 阅读(53) 评论(0) 编辑 收藏 举报