使用合约管理钱包

代码备份

// 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编辑  收藏  举报

导航