solidity create2 学习

简介: solidity create2 学习
salt

nonce,也可以自己生成

create

address = hash(msg.sender,nonce)

create2

deploymentData= creationCode+constructorArgs

address =hash(“0xff”,msg.sender,nonce,hash(deploymentData))

可以不用部署直接可以获取合约地址

address(this)

相当于A合约中调用了B(uint)的构造方法创建了B合约

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

contract A{
   function test8() public pure returns (bytes4 a,bytes4 b){
     //获取methodId
     //合约名字,方法名字
      a = B.getBalance.selector;
      b = bytes4(keccak256(abi.encodePacked("getBalance()")));
   }

    function testCreate2(uint _number) public  returns (address bAddr){
        //获取createCode
        bytes memory cCode = type(B).creationCode;
        //构造方法参数编码
        bytes memory args = abi.encode(_number);
        //生成bytescode
        bytes memory deploymentData =  abi.encodePacked(cCode,args);
        //利用参数生成salt
        bytes32 salt = keccak256(abi.encodePacked(_number));
         assembly {
            bAddr := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
        }
        require(address(bAddr) != address(0), "Create2 call failed");
    }

     // 提前计算合约地址
        function calculateAddr(uint _number) public view returns(address bAddr){

         //获取createCode
        bytes memory cCode = type(B).creationCode;
        //构造方法参数编码
        bytes memory args = abi.encode(_number);
        //生成bytescode
        bytes memory deploymentData =  abi.encodePacked(cCode,args);
        //利用参数生成salt
        bytes32 salt = keccak256(abi.encodePacked(_number));
            // 计算合约地址方法 hash()
            bytes memory params =   abi.encodePacked(
                bytes1(0xff),
                address(this),
                salt,
                keccak256(deploymentData)
            );
            bytes32  params2 = keccak256(params);
            uint params3 =  uint(params2);
            bAddr = address(uint160(params3));
        }

}


contract B{

    uint public b = 10;
    constructor(uint _b) public{
        b = _b;
    }

    event anTest(uint indexed addr) anonymous;
    
    function getBalance() view public returns (uint){
      return address(this).balance;
    }
    receive () payable external{
        emit anTest(msg.value);
    }

    fallback () payable external{

    }

}


clone-factory
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;


contract TestA{
    uint public a;

    constructor(){}

    function setA(uint _a)public {
        a = _a;
    }
    function getAB(uint b) view public  returns (uint c){
        c= a+b;
    }

}


contract ContractFactory{
    address public implementation;
    bytes public code;
    bytes32 public codeHash;   
    event ProxyCreated(address indexed _address, bytes32 _salt);
    event ImplementationChanged(address indexed _implementation, bytes32 _codeHash, bytes _code);

   
    function getSalt(uint _number)  pure public returns (bytes32){
        return keccak256(abi.encodePacked(_number));
    }

    function setImplementation(address _implementation) public {
        require(
            _implementation != address(0),
            "ContractFactory#_setImplementation: INVALID_IMPLEMENTATION"
        );
        // Adapted from https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol
        code = abi.encodePacked(
            hex"3d602d80600a3d3981f3363d3d373d3d3d363d73",
            _implementation,
            hex"5af43d82803e903d91602b57fd5bf3"
        );
        codeHash = keccak256(code);
        implementation = _implementation;

        emit ImplementationChanged(implementation, codeHash, code);
    }

     function getAddress(uint _number) public view returns (address _addr) {
        return address(
            uint160(uint256(
                keccak256(
                    abi.encodePacked(
                        bytes1(0xff),
                        address(this),
                        getSalt(_number),
                        codeHash
                    )
                )
            ))
        );
    }
    function createProxy(uint _number, bytes memory _data) public virtual returns (address addr) {
        bytes memory slotcode = code;
        // solium-disable-next-line security/no-inline-assembly
        bytes32 salt  = getSalt(_number);
        assembly {
            addr := create2(0, add(slotcode, 0x20), mload(slotcode), salt)
        }
        require(addr != address(0), "ContractFactory#createProxy: CREATION_FAILED");

        emit ProxyCreated(addr, salt);

        if (_data.length > 0) {
            (bool success,) = addr.call(_data);
            require(success, "ContractFactory#createProxy: CALL_FAILED");
        }
    }

  
}


shr shl使用 两个值生成唯一的值,通过唯一值获取对应的两个值


  function encodeTokenId(uint256 _itemId, uint256 _issuedId) public pure returns (uint256 id) {
        require(_itemId <= MAX_ITEM_ID, "encodeTokenId: INVALID_ITEM_ID");
        require(_issuedId <= MAX_ISSUED_ID, "encodeTokenId: INVALID_ISSUED_ID");

        // solium-disable-next-line security/no-inline-assembly
        assembly {
            id := or(shl(ISSUED_ID_BITS, _itemId), _issuedId)
        }
    }

    /**
     * @notice Decode token id
     * @dev itemId (`itemIdBits` bits) + issuedId (`issuedIdBits` bits)
     * @param _id - token id
     * @return itemId uint256 of the item id
     * @return issuedId uint256 of the issued id
     */
    function decodeTokenId(uint256 _id) public pure returns (uint256 itemId, uint256 issuedId) {
        uint256 mask = MAX_ISSUED_ID;
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            itemId := shr(ISSUED_ID_BITS, _id)
            issuedId := and(mask, _id)
        }
    }
相关文章
|
人工智能 安全 区块链
零知识证明:隐私保护的新前沿
【6月更文挑战第13天】零知识证明是种密码学技术,允许证明者向验证者证明陈述的真实性而不透露任何信息。这种技术基于数学难题,应用于隐私保护身份验证、区块链交易和敏感数据共享,保护用户隐私的同时确保安全性。尽管面临计算复杂度高和安全验证等挑战,零知识证明有望与区块链、AI等技术结合,为隐私保护领域带来创新突破。
|
21天前
|
XML Java 数据格式
Bean的生命周期:从Spring的子宫到坟墓
Spring 管理 Bean 的生命周期,从对象注册、实例化、属性注入、初始化、使用到销毁,全程可控。Bean 的创建基于配置或注解,Spring 在容器启动时扫描并生成 BeanDefinition,按需实例化并填充依赖。通过 Aware 回调、初始化方法、AOP 代理等机制,实现灵活扩展。了解 Bean 生命周期有助于更好地掌握 Spring 框架运行机制,提升开发效率与系统可维护性。
|
JavaScript 前端开发 区块链
|
8月前
|
数据采集 JavaScript 前端开发
京东商品详情 API 接口指南(Python 篇)
本简介介绍如何使用Python抓取京东商品详情数据。首先,需搭建开发环境并安装必要的库(如requests、BeautifulSoup和lxml),了解京东反爬虫机制,确定商品ID获取方式。通过发送HTTP请求并解析HTML,可提取价格、优惠券、视频链接等信息。此方法适用于电商数据分析、竞品分析、购物助手及内容创作等场景,帮助用户做出更明智的购买决策,优化营销策略。
|
11月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
173 0
Linux C/C++之线程基础
|
项目管理
技术探索的心得与反思
在技术的海洋中,每一次深入都如同揭开未知领域的神秘面纱。本文将分享一些个人在技术领域探索中的感悟和反思。
|
11月前
|
消息中间件 Java Kafka
Kafka ACK机制详解!
本文深入剖析了Kafka的ACK机制,涵盖其原理、源码分析及应用场景,并探讨了acks=0、acks=1和acks=all三种级别的优缺点。文中还介绍了ISR(同步副本)的工作原理及其维护机制,帮助读者理解如何在性能与可靠性之间找到最佳平衡。适合希望深入了解Kafka消息传递机制的开发者阅读。
998 0
|
存储 前端开发 JavaScript
深入浅出React框架:构建高效组件化网页的实战指南
【7月更文挑战第9天】在当今快速发展的前端技术领域,React凭借其强大的组件化思想、高效的虚拟DOM以及丰富的生态系统,成为了构建动态用户界面的首选框架之一。本文将带你深入浅出地探索React的核心概念,并通过实战示例,展示如何利用React构建高效、可维护的组件化网页。
279 8
修改了node_modules的文件打包后不生效
修改了node_modules的文件打包后不生效
1635 1
|
程序员 Python
利用Python实现科学式占卜
一直以来,中式占卜都是基于算命先生手工实现,程序繁琐(往往需要沐浴、计算天时、静心等等流程)。准备工作复杂(通常需要铜钱等道具),计算方法复杂,需要纯手工计算二进制并转换为最终的卦象,为了解决这个问题,笔者基于python实现了一套科学算命工具,用于快速进行占卜。 本文的算命方式采用八卦 + 周易+ 梅花易数实现,脚本基于python3.9.0开发。本人对于周易五行研究较浅,如有疏漏请见谅。 最终效果如图,在运行程序之后,会根据当前的运势自动获取你心中所想之事的卦象(本卦、互卦、变卦) 前置知识 基础原理 首先我们需要了解一些最基本的占卜知识,目前我国几种比较主流的占卜方式基本都是基
225 0