Ethereum(以太坊)里的那些事之第二篇

风险提示

根据银保监会等五部门于 2018 年 8月发布《关于防范以「虚拟货币」「区块链」名义进行非法集资的风险提示》的文件, 请广大公众理性看待区块链,不要盲目相信天花乱坠的承诺,树立正确的货币观念和投资理念,切实提高风险意识;对发现的违法犯罪线索,可积极向有关部门举报反映。

前情提示

上一篇文章大致讲了下什么是区块链和一个最基础的智能合约。合约基础到什么程度呢,基础到只有一个函数。这一篇文章主要带来一个具有写入函数以及权限控制的智能合约。因为是由浅入深,所以跨度不会太大,希望大家可以理解。话不多说,咱们直奔主题。

主题:我就是主题

智能合约的代码如下:

solidity 复制代码
contract SimpleStorage {
    uint public num;

    address internal owner;

    event LogSet(address owner, address caller);

    constructor() {
        owner = msg.sender;
    }

    function set(uint _num) public {
        emit LogSet(owner, msg.sender);
        require(msg.sender == owner, "no permission");
        num = _num;
    }

    function get() public view returns (uint) {
        return num;
    }

    function getOwner() external view returns(address) {
        return owner;
    }
}

Try on Remix

从代码里我们可以看到,定义一个类型为 uint256 且可见性为public的变量num和一个类型为 address 且可见性为internal的变量owner, 且在构造函数里将msg.sender 赋值给 owenr。 msg.sender 是由 solidity 内置的一个东西,其值是变化的。如果是钱包AddressA 部署了 SimpleStorage 合约,则 msg.sender 就是钱包AddressA的地址。如果 SimpleStorage 是通过合约 B 部署的,则 msg.sender 就是合约B的地址。着重看下权限控制代码

ini 复制代码
require(msg.sender == owner, "no permission");

这里通过内置函数require来检查权限,require函数接受两个参数,第一个参数是条件判断表达式,是必选的,第二个参数为要返回的异常消息提醒,该参数是可选的。如果第一个参数的结果为true,则执行require下面的代码,反之则抛出异常,后续的代码也不会执行。

话题好像跑远了,应该测试下功能的😅,为了方便查看owner和函数调用者,我特意加了一个LogSet事件

csharp 复制代码
event LogSet(address owner, address caller);

该事件抛出了owner和函数调用者

scss 复制代码
emit LogSet(owner, msg.sender);

调用set函数并传入参数10,我们看到了输出日志里 owner和caller地址都是我们账户地址0x5B38Da6a701c568545dCfcB03FcB875f56beddC4,并且 num已经被成功设置为10

那如果调用者不是合约的owner呢,让我们眼见为实

如上图所示,我将账户切换为0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,并传参20给set函数,其结果是合约直接拒绝并抛出错误"no permission",并且num依旧是10,这就意味着权限控制生效了。

题外话

既然讲到了通过合约部署合约,那我们就来测试一下。代码如下:

solidity 复制代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface ISimpleStorage {
    function getOwner() external returns(address);
}

contract SimpleStorage {
    uint public num;

    address internal owner;

    constructor() {
        owner = msg.sender;
    }

    function set(uint _num) public {
        require(msg.sender == owner, "no permission");
        num = _num;
    }

    function get() public view returns (uint) {
        return num;
    }

    function getOwner() external view returns(address) {
        return owner;
    }
}

contract FactoryContract {
    address public owner;

    uint public index;

    constructor() {
        owner = msg.sender;
    }

    function createContract() public returns(address) {
        address c = address(new SimpleStorage{salt: keccak256(abi.encode(msg.sender, index))}());

        index += 1;

        return c;
    }

    function getSimpleStorageOwner(address _addr) public returns(address) {
            return ISimpleStorage(_addr).getOwner();
    }
}

可以看到我们在 FactoryContract 合约里直接通过 new关键字直接创建合约。

我们试试通过 Factory 合约部署 SimpleStorage。

  1. 第一步,我们部署 Factory 合约(地址为:0xDA0bab807633f07f013f94DD0E6A4F96F8742B53),并调用 createContract 函数,并通过函数的返回值拿到了 SimpleStorage 合约地址为 0xAE77aeafd5569aa06Eef08Aff16Ba04e792AEf0f
  1. 第二步,我们通过调用FactoryContract的getSimpleStorageOwner 函数,并传入刚刚 拿到的 SimpleStorage 地址

调用FactoryContract的getSimpleStorageOwner,我们拿到了合约0xAE77aeafd5569aa06Eef08Aff16Ba04e792AEf0f 的owner为0xDA0bab807633f07f013f94DD0E6A4F96F8742B53,和Factory合约地址是一致的。

下集预告

这篇文章主要是给大家介绍了权限控制以及通过合约创建合约,下篇给大家讲下如何通过智能合约实现接收和发送Ether(老值钱了)。

相关推荐
dingzd9515 小时前
结合指纹防护技术,释放Web3去中心化的潜力
web3·去中心化·区块链·facebook·tiktok·instagram·clonbrowser
OEC小胖胖15 小时前
去中心化身份:2025年Web3身份验证系统开发实践
前端·web3·去中心化·区块链
长安链开源社区10 天前
长安链浏览器「数据看板」 高效洞察数据状态与趋势
web3·区块链·共识算法
MicroTech202510 天前
微算法科技(NASDAQ:MLGO)研发可信共识算法TCA,解决区块链微服务中的数据一致性与安全挑战
运维·算法·区块链·共识算法
闲坐含香咀翠10 天前
Hyperledger Fabric 联盟链网络实操部署指南(二)
区块链
闲坐含香咀翠10 天前
Hyperledger Fabric 联盟链网络实操部署指南(一)
区块链
闲坐含香咀翠10 天前
Fabric联盟链框架开发学习路线指南
区块链
Listennnn11 天前
稳定币是什么、为什么会出现
区块链
代码羊羊11 天前
Solidity内部合约创建全解析:解锁Web3开发新姿势
web3·区块链
白总Server11 天前
轻量化分布式AGI架构:基于区块链构建终端神经元节点的互联网智脑
分布式·microsoft·中间件·架构·区块链·github·agi