年轻人的第一个智能合约

年轻人,是否想拥有你的第一个智能合约?

下面,我们将一起在 Remix 上编写、部署和测试年轻人的第一个智能合约,该合约实现了一个简单的区块链通讯录,主要包括如下几个功能:

  • 添加联系人,包括姓名和手机号;
  • 查询所有联系人姓名;
  • 查询指定联系人的手机号;

合约概览

智能合约代码使用 Solidity 编写,完整的代码如下所示:

solidity 复制代码
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

contract BlockChainContactList {
    
    //"王五","13598534006"
    mapping(string => string) private nameToPhone;
    // 用于存储所有的名字
    string[] private names; 

    function addContact(string calldata _name, string calldata _phone) public {
        // 如果是新联系人,则添加到数组中
        if(bytes(nameToPhone[_name]).length == 0) { 
            names.push(_name);
        }
        nameToPhone[_name] = _phone;
    }

    function getContact(string calldata _name) public view returns (string memory) {
        return nameToPhone[_name];
    }

    function getAllContactNames() public view returns (string[] memory) {
        return names;
    }
}

Solidity 代码详解

下面我们来详细看一下上述代码的各个组成部分

许可声明

solidity 复制代码
// SPDX-License-Identifier: MIT

这行代码是一个 SPDX 许可证标识符注释,用于明确指定智能合约源代码的许可证类型。上面的代码表明该智能合约遵循 MIT 许可,属于非常宽松的一种许可,允许人们几乎无任何限制地使用、复制、修改和分发软件,唯一的要求是在软件的所有副本和重要的文档内容中都必须包含版权声明和许可声明。

Solidity 版本声明

solidity 复制代码
pragma solidity 0.8.24;

这行代码是Solidity语言中的一个编译指令,用于指定智能合约的编译器版本。这行代码告诉Solidity编译器,该合约是为Solidity版本0.8.24编写的,因此编译这个合约时应该使用版本0.8.24的编译器。除了上述指定版本的写法,还可以通过如下方式,指定版本的范围:

solidity 复制代码
pragma solidity ^0.8.0; //表示合约兼容Solidity 0.8.0及以上的版本,但小于0.9.0(不包含0.9.0)。
pragma solidity >=0.8.0 <0.9.0; //具有相同的意义,表示合约兼容的版本范围是从0.8.0(包含)到0.9.0(不包含)

智能合约定义

solidity 复制代码
contract BlockChainContactList {
    ............
}

上面的代码在 Solidity 中定义了一个名为 BlockChainContactList 的智能合约。在Solidity语言中,contract关键字用于声明一个新的智能合约,类似于许多面向对象编程语言中的 class 关键字。智能合约是区块链上的一个程序,它包含了一组规则以及这些规则的自动执行逻辑。一旦部署到区块链上,智能合约在交易触发时按照编写的逻辑自动执行操作。

合约变量定义

solidity 复制代码
    //"王五","13598534006"
    mapping(string => string) private nameToPhone;
    // 用于存储所有的名字
    string[] private names; 

上面的代码定义了两个private变量,只能够被合约内部的函数访问。其中一个是map类型的变量,一个是array类型的变量。

合约函数定义

solidity 复制代码
    function addContact(string calldata _name, string calldata _phone) public {
        // 如果是新联系人,则添加到数组中
        if(bytes(nameToPhone[_name]).length == 0) { 
            names.push(_name);
        }
        nameToPhone[_name] = _phone;
    }

    function getContact(string calldata _name) public view returns (string memory) {
        return nameToPhone[_name];
    }

    function getAllContactNames() public view returns (string[] memory) {
        return names;
    }

上面的代码,定义了三个智能合约函数,public 意味着函数可以被智能合约外部访问。

  • addContact 接收两个参数,没有返回值,用于添加通讯录信息;
  • getContact 接收一个参数,返回一个参数,用于查询指定联系人的手机号;
  • getAllContactNames 没有参数,返回一个参数,用于查询通讯录中的所有联系人姓名;

上面的代码中,可以看到参数和返回值有calldatamemory两个关键字,它们是用来指定数据的存储位置和可变性。

calldata是一个不可修改的temporary存储区域。当函数有外部参数时,这些参数是完全存储在calldata区域中。对calldata区域的数据访问不会产生任何副本,因为它只是直接从调用数据中读取。由于calldata区域是不可修改的,所以在函数内部不能修改通过calldata传入的参数。
memory是一个可变的临时存储区域,用于存储可变数据。每次函数调用时,都会为memory分配新的空间。从memory中分配新的对象时会创建对象的一个全新副本。通过值传递方式在函数中修改memory中的变量不会影响外部变量。

编译、部署和测试

上述智能合约的编译、部署和测试均在Remix中进行。Remix是一个强大的开源Web和桌面应用程序,专为以太坊智能合约的开发、测试、部署和调试而设计。它支持Solidity语言,是以太坊开发者社区中广泛使用的一个工具。Remix提供了一个用户友好的界面,使得无论是经验丰富的开发者还是刚入门的新手都能轻松上手。

编译

将代码贴到Remix中之后,点击左侧的编译图标。

选择对应版本的编译器,点击编译按钮。

部署

编译完成后,点击部署图标。

选择部署的环境(Remix虚拟环境)、账户(Remix提供的测试账户),点击部署按钮。部署成功后,左下角即出现部署好的智能合约可以被调用的函数。

部署成功后,在控制台可以看到该笔交易的详情(对区块链做的任何修改的操作,实质上都是发起了交易)。其中的input,就是编译后的智能合约的内容。

测试

部署完智能合约之后,就可以调用合约的函数来进行测试。

调用addContact函数

调用getAllContactNames函数

调用getContact函数

相关推荐
CoovallyAIHub7 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP8 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo8 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo8 小时前
300:最长递增子序列
算法
CoovallyAIHub13 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub14 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农2 天前
【React用到的一些算法】游标和栈
算法·react.js