`

Transparent

 
阅读更多
Transparent:
a.如果Proxy合约发现自己被ProxyAdmin合约调用,那么它会调用自身的函数代码;如果调用者是ProxyAdmin之外的账户,那么它会通过delegatecall去调用Implementation的代码。这样就保障了合约升级的安全性。
b.升级函数在proxy里面,proxy里面的函数基本都有ifAdmin修饰符校验

TransparentAdmin.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0;
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import "hardhat/console.sol";
import "./TransparentProxy.sol";

contract TransparentAdmin is ProxyAdmin {
    constructor() 
     {}
    
    function fun(address payable addr) external payable {
        TransparentProxy proxy = TransparentProxy(addr);
        proxy.fun();
    }

}


TransparentImplement.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0;
import "hardhat/console.sol";

contract TransparentImplement {
    uint num;
    address addr;
    constructor() {
        num = 1;
        addr = msg.sender;
    }

    function fun() external {
        num = 2;
        addr = msg.sender;
        console.log("logic fun");
    }
}


TransparentImplementNew
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0;
import "hardhat/console.sol";

contract TransparentImplementNew {
    uint num;
    address addr;
    uint num2;
    constructor() {
        num = 1;
        addr = msg.sender;
    }

    function fun() external {
        num = 3;
        addr = address(this);
        num2 = 100;
        console.log("new logic fun");
    }
}


TransparentProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0;
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "hardhat/console.sol";

contract TransparentProxy is TransparentUpgradeableProxy {
    constructor(address _logic, address admin_, bytes memory _data) 
    TransparentUpgradeableProxy(_logic,admin_,_data) {}

    function fun() external ifAdmin{
        console.log("proxy fun");
    }
}


测试
const { ethers } = require("hardhat")
const web3 = require("web3")

contractProxy = "TransparentProxy";
contractAdmin = "TransparentAdmin";
contractImpl = "TransparentImplement";
contractImplNew = "TransparentImplementNew";


async function getSlots(proxy){
    let slot0 = await ethers.provider.getStorageAt(proxy.address, 0)
    console.log("slot0:",slot0);

    let slot1 = await ethers.provider.getStorageAt(proxy.address, 1)
    console.log("slot1:",slot1);

    let slot2 = await ethers.provider.getStorageAt(proxy.address, 2)
    console.log("slot2:",slot2);
}

function getFunctionSeletor(funcHead) {
    return ethers.utils.id(funcHead).slice(0,10)
}

describe("transparent1", function () {
  it("transparent ", async function () {
    const ContractAdmin = await ethers.getContractFactory(contractAdmin);
    const admin = await ContractAdmin.deploy();
    console.log("admin addr:",admin.address);

    const ContractImpl = await ethers.getContractFactory(contractImpl);
    const impl = await ContractImpl.deploy();
    console.log("impl addr:",impl.address);

    const ContractProxy = await ethers.getContractFactory(contractProxy);
    const data = Buffer.from('');//string转bytes
    const proxy = await ContractProxy.deploy(impl.address,admin.address,data);
    console.log("proxy:",proxy.address);

    console.log("通过admin调用proxy.fun():");
    await admin.fun(proxy.address)
    console.log("通过proxy调用proxy.fun():");
    await proxy.fun();
    console.log("升级前逻辑合约地址:", await admin.getProxyImplementation(proxy.address));
    console.log("proxy 槽信息:")
    getSlots(proxy);
    
    
    const ContractImplNew = await ethers.getContractFactory(contractImplNew);
    const implNew = await ContractImplNew.deploy();
    console.log("new impl addr:",implNew.address);
    console.log("升级并通过proxy调用proxy.fun():");
    //const selector = getFunctionSeletor("fun()").split('').join('')
    let interface = new ethers.utils.Interface([
        "function fun()"
    ]);
    let calldata = interface.encodeFunctionData("fun", [])
    await admin.upgradeAndCall(proxy.address,implNew.address,calldata);
    await getSlots(proxy);
    console.log("升级后逻辑合约地址:", await admin.getProxyImplementation(proxy.address));
  });
});


transparent1
admin addr: 0x5FbDB2315678afecb367f032d93F642f64180aa3
impl addr: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
proxy: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
通过admin调用proxy.fun():
proxy fun
通过proxy调用proxy.fun():
logic fun
升级前逻辑合约地址: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
proxy 槽信息:
slot0: 0x0000000000000000000000000000000000000000000000000000000000000002
slot1: 0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266
slot2: 0x0000000000000000000000000000000000000000000000000000000000000000
new impl addr: 0x5FC8d32690cc91D4c39d9d3abcBD16989F875707
升级并通过proxy调用proxy.fun():
new logic fun
slot0: 0x0000000000000000000000000000000000000000000000000000000000000003
slot1: 0x0000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e0
slot2: 0x0000000000000000000000000000000000000000000000000000000000000064
升级后逻辑合约地址: 0x5FC8d32690cc91D4c39d9d3abcBD16989F875707
分享到:
评论

相关推荐

    Real Transparent Form C#

    "Real Transparent Form C#"是一个专题,关注于如何在WinForms中实现真正意义上的透明窗体,尤其是在使用PNG图像作为背景时。这个专题的核心是提供一个类,解决了在设置窗体背景为PNG图片时可能出现的问题。 在...

    FlyFi_Transparent_2.0

    《FlyFi_Transparent_2.0:无线网络的便捷转换工具》 在信息化飞速发展的今天,无线网络已经成为我们日常生活和工作的重要组成部分。"FlyFi_Transparent_2.0"是一款专为用户提供无线网卡与无线路由器功能转换的实用...

    the-transparent-loading_piccompany_

    标题中的"the-transparent-loading_piccompany_"似乎是一个组合关键词,它可能代表了某个特定的项目或者功能,其中"transparent-loading"可能是指一个具有透明加载效果的元素,而"piccompany"可能是这个项目或功能的...

    Transparent Bitmap实现透明的位图(7KB)

    本文将围绕“Transparent Bitmap实现透明的位图”这一主题,详细介绍透明位图的概念、实现方式以及在不同编程环境中的应用。 首先,透明位图的核心是透明度通道(Alpha Channel)。在标准的RGB颜色模型中,每个像素...

    Oracle Transparent Gateway for Microsoft SQLServer

    ### Oracle Transparent Gateway for Microsoft SQL Server 知识点详解 #### 一、概述 **Oracle Transparent Gateway for Microsoft SQL Server**(以下简称“透明网关”)是一款由Oracle公司开发的产品,旨在实现...

    VC6 Transparent Dialog

    这个"VC6 Transparent Dialog"项目提供了一种简单的方法来实现这一功能。 首先,我们要理解Windows API中与透明性相关的概念。在Windows系统中,窗口的透明度是通过指定窗口类的风格来实现的,比如WS_EX_LAYERED...

    Transparent Gateway for Sybase

    ### 透明网关(Transparent Gateway)为Sybase的官方文档解析 #### 一、透明网关简介 **透明网关**(Transparent Gateway)是Oracle提供的一款高性能的数据访问中间件产品,它允许用户通过标准的SQL语句直接访问...

    pb 窗口 控件 透明 transparent pb9

    标题中的“pb 窗口 控件 透明 transparent pb9”指的是使用PowerBuilder(PB)开发的窗口应用程序中实现控件透明的技术。PowerBuilder是一种基于事件驱动的编程环境,广泛用于构建图形用户界面(GUI)应用程序。在PB...

    ORACLE advanced Security - Transparent Data Encryption

    Oracle Database 11g通过引入透明数据加密(Transparent Data Encryption, TDE)技术,提供了一种有效的方法来保护存储在数据库中的敏感数据。本文档将深入探讨Oracle Database 11g TDE的功能及其与nCipher硬件安全...

    Android代码-transparent-over-animtabsview

    "Android代码-transparent-over-animtabsview"项目就是一个很好的实例,它展示了如何实现类似网易云音乐首页Tab切换时的动态透明三角形效果。这个开源项目旨在帮助开发者理解和应用这种交互设计,为自己的应用增添...

    透明的对话框transparent_dialog.rar

    // black the transparent color memDC.SetBkColor(RGB(0,0,0)); memDC.SetTextColor(RGB(255,255,255)); memDC.BitBlt(0, 0, nWidth, nHeight, &maskDC, 0, 0, SRCAND); // Set the foreground to black. ...

    unity获取Transparent的深度信息

    在Unity引擎中,透明(Transparent)材质通常用于创建半透明或完全透明的物体,例如玻璃、烟雾或粒子效果。然而,透明物体的深度信息处理与不透明物体不同,这可能导致在渲染时出现一些视觉问题,如重影、排序错误等...

    Transparent-Delegate-Toolbar,一个简单的Android透明工具栏.zip

    "Transparent-Delegate-Toolbar"是一个开源项目,专注于实现Android应用中的透明工具栏效果。这个项目旨在帮助开发者轻松创建具有动态透明度变化的工具栏,提升用户体验,尤其是在使用滑动滚动视图时。 1. **透明...

    Actual Transparent Windows

    《Actual Transparent Windows——让桌面美化更上一层楼》 在数字化的世界里,用户对桌面环境的个性化需求日益增长,而“Actual Transparent Windows”正是这样一款致力于提升桌面美学体验的软件。这款工具允许用户...

    wince Transparent image

    上述代码创建了一个具有透明背景的窗体,并加载了一张名为"transparent_image.png"的图像。由于设置了窗体的BackColor为Color.Transparent,窗体背景将与父窗口的颜色相混合。pictureBox控件用于显示图像,其...

    Flexible, transparent and high-power triboelectric generator with asymmetric graphene/ITO electrodes

    标题中的“Flexible, transparent and high-power triboelectric generator with asymmetric graphene/ITO electrodes”指的是一个创新性的科研成果,即一种基于石墨烯/ITO非对称电极的柔性透明高功率摩擦发电机。...

    Modelling with Transparent Soils

    第八章为DIC数字图像相关 Modelling with Transparent Soils Visualizing Soil Structure Interaction and Mult.

    transparent001 登录页面以及系统

    transparent001 登录页面以及系统transparent001 登录页面以及系统transparent001 登录页面以及系统transparent001 登录页面以及系统transparent001 登录页面以及系统transparent001 登录页面以及系统transparent001...

    Actual Transparent Windows(窗口透明工具) v8.14.zip

    Actual Transparent Windows是一款简单好用的窗口透明工具软件。软件帮助用户将Windwos下的程序窗口改为透明显示,增加透明效果,从而达到类似win7系统窗口的效果。除此之外,软件还能实现设定启动时、拖动窗口时、...

    transparent.php

    transparent.php

Global site tag (gtag.js) - Google Analytics