佛萨奇2.0智能合约系统开发(参考版)丨佛萨奇2.0系统源码案例部署

简介: Solidity中智能合约的含义就是一组代码(它的功能)和数据(它的状态)的集合,并且它们是位于以太坊区块链的一个特定地址上的。uintstoredData;这一行代码声明了一个名为``storedData``的状态变量,其类型为uint(256位无符号整数)。 你也可以认为它是数据库里的一个插槽,并且可以通过调用管理数据库代码的函数进行查询和更改。在这个例子中,上述的合约定义了``set``和``get`` 函数,可以用来修改或检索变量的值。

1、存储合约示例

把一个数据保存到链上

// SPDX-License-Identifier: GPL-3.0

pragma solidity>=0.4.16<0.9.0;

contractSimpleStorage{

uintstoredData;

functionset(uintx)public{

storedData=x;

}

functionget()public view returns(uint){

returnstoredData;

}

}

第一行是说明源代码是根据GPL 3.0版本授权的。默认情况下,在发布源代码时加入机器可读许可证说明是很重要的,

下一行是告诉编译器源代码所适用的Solidity版本为>=0.4.16 及 pragma是告知编译器如何处理源代码的通用指令(例如,pragma once)。

Solidity中智能合约的含义就是一组代码(它的功能)和数据(它的状态)的集合,并且它们是位于以太坊区块链的一个特定地址上的。uintstoredData;这一行代码声明了一个名为storedData的状态变量,其类型为uint(256位无符号整数)。 你也可以认为它是数据库里的一个插槽,并且可以通过调用管理数据库代码的函数进行查询和更改。在这个例子中,上述的合约定义了setget 函数,可以用来修改或检索变量的值。

要访问当前合约的成员(如:状态变量),通常不需要像添加this.这样的前缀,你只需要通过名字就可以直接访问它。 与其他一些语言不同的是,省略它不仅仅是一个风格问题,因为它是一种完全不同的访问成员的方式,这一块后面会详细介绍。

该合约能完成的事情并不多(由于以太坊构建的基础架构的原因):它能允许任何人在合约中存储一个单独的数字,并且这个数字可以被世界上任何人访问,且没有可行的办法阻止你发布这个数字。当然,任何人都可以再次调用set,传入不同的值,覆盖你的数字,但是这个数字仍会被存储在区块链的历史记录中。随后,我们会看到怎样施加访问限制,以确保只有你才能改变这个数字。

2、货币合约(Subcurrency)示例

下面的合约实现了一个最简单的加密货币。这里,币确实可以无中生有地产生,但是只有创建合约的人才能做到(实现一个不同的发行计划也不难)。而且,任何人都可以给其他人转币,不需要注册用户名和密码 —— 所需要的只是以太坊密钥对。

// SPDX-License-Identifier: GPL-3.0

pragma solidity^0.8.4;

contractCoin{

// 关键字“public”让这些变量可以从外部读取

addresspublic minter;

mapping(address=>uint)publicbalances;

// 轻客户端可以通过事件针对变化作出高效的反应

eventSent(addressfrom,addressto,uintamount);

// 这是构造函数,只有当合约创建时运行

constructor(){

minter =msg.sender;

}

functionmint(addressreceiver,uintamount)public{

require(msg.sender== minter);

balances[receiver]+=amount;

}

// Errors allow you to provide information about

// why an operation failed. They are returned

// to the caller of the function.

error InsufficientBalance(uintrequested,uintavailable);

functionsend(addressreceiver,uintamount)public{

if(amount > balances[msg.sender])

revert InsufficientBalance({

requested: amount,

available: balances[msg.sender]

});

balances[msg.sender]-= amount;

balances[receiver]+=amount;

emit Sent(msg.sender, receiver, amount);

}

}

这个合约引入了一些新的概念,让我们逐一解读。

addresspublicminter;这一行声明了一个可以被公开访问的address类型的状态变量。address类型是一个160位的值,且不允许任何算数操作。这种类型适合存储合约地址或外部人员的密钥对。关键字public自动生成一个函数,允许你在这个合约之外访问这个状态变量的当前值。如果没有这个关键字,其他的合约没有办法访问这个变量。由编译器生成的函数的代码大致如下所示(暂时忽略 external 和 view):

functionminter()external view returns(address){return minter;}

当然,加一个和上面完全一样的函数是行不通的,因为我们会有同名的一个函数和一个变量,这里,主要是希望你能明白——编译器已经帮你实现了。

下一行,mapping(address=>uint)publicbalances;也创建一个公共状态变量,但它是一个更复杂的数据类型。 该类型将address映射为无符号整数。 Mappings 可以看作是一个哈希表它会执行虚拟初始化,以使所有可能存在的键都映射到一个字节表示为全零的值。 但是,这种类比并不太恰当,因为它既不能获得映射的所有键的列表,也不能获得所有值的列表。 因此,要么记住你添加到mapping中的数据(使用列表或更高级的数据类型会更好),要么在不需要键列表或值列表的上下文中使用它,就如本例。 而由public关键字创建的getter函数getter function则是更复杂一些的情况, 它大致如下所示:

functionbalances(addressaccount)external view returns(uint){

return balances[account];

}

正如你所看到的,你可以通过该函数轻松地查询到账户的余额。

eventSent(addressfrom,addressto,uintamount);这行声明了一个所谓的“事件(event)”,它会在send函数的最后一行被发出。用户界面(当然也包括服务器应用程序)可以监听区块链上正在发送的事件,而不会花费太多成本。一旦它被发出,监听该事件的listener都将收到通知。而所有的事件都包含了from,to和amount三个参数,可方便追踪交易。 为了监听这个事件,你可以使用如下JavaScript代码(假设 Coin 是已经通过web3.js 创建好的合约对象):

Coin.Sent().watch({},'',function(error,result){

if(!error){

console.log("Coin transfer: "+result.args.amount+

" coins were sent from "+result.args.from+

" to "+result.args.to+".");

console.log("Balances now:\n"+

"Sender: "+Coin.balances.call(result.args.from)+

"Receiver: "+Coin.balances.call(result.args.to));

}

})

这里请注意自动生成的balances函数是如何从用户界面调用的。

特殊函数constructor是仅在创建合约期间运行的构造函数,不能在创建之后调用。 在 Coin 合约中,构造函数永久存储创建合约的人的地址:msg(类似的还有tx和block) 是一个特殊的全局变量, 参考特殊变量和函数,这些变量允许我们访问区块链的属性。msg.sender始终记录当前(外部)函数调用是来自于哪一个地址。

最后,真正被用户或其他合约所调用的,以完成本合约功能的方法是mint和send。

mint函数用来新发行一定数量的币到一个地址。require用来检查某些条件,如果不满足这些条件就会回推所有的状态变化。 在这个例子中,require(msg.sender==minter);确保只有合约的创建者可以调用mint。 一般来说,创建者可以随心所欲地铸造代币,但在某些时候,这将导致一种叫做 “溢出” 的现象。

请注意,由于默认的算术检查模式,如果表达式balances[receiver]+=amount;溢出交易将被还原。 即当任意精度算术中的balances[receiver]+amount大于uint(2**256-1)。同样在在函数send中的balances[receiver]+=amount;这对语句来说也是如此。

Errors用来向调用者描述错误信息。Error与revert 语句一起使用。revert语句无条件地中止执行并回退所有的变化,类似于require函数,它也同样允许你提供一个错误的名称和额外的数据,这些额外数据将提供给调用者(并最终提供给前端应用程序或区块资源管理器),这样就可以更容易地调试或应对失败。

任何人(已经拥有一些代币)都可以使用send函数来向其他人发送代币。如果发送者没有足够的代币可以发送,if条件为真revert将触发失败,并通过InsufficientBalance向发送者提供错误细节。

如果mint被合约创建者外的其他人调用则什么也不会发生。 另一方面,send函数可被任何人用于向他人发送币 (当然,前提是发送者拥有这些币)。记住,如果你使用合约发送币给一个地址,当你在区块链浏览器上查看该地址时是看不到任何相关信息的。因为,实际上你发送币和更改余额的信息仅仅存储在特定合约的数据存储器中。通过使用事件,你可以非常简单地为你的新币创建一个“区块链浏览器”来追踪交易和余额。

相关文章
|
6月前
|
存储 安全 区块链
DAPP持币生息系统开发|模式案例|开发指南
智能合约是一种计算机协议,在协议制定和部署后,不需要外加人为干预,即可实现自我执行和自我验证
|
6月前
|
区块链 数据库 数据安全/隐私保护
DAPP持币生息系统开发|源码部署|详情方案
随着互联网技术的飞速发展,人类社会正在经历着数字化、全球化和智能化的快速转型。
|
6月前
|
存储 区块链 数据安全/隐私保护
DAPP佛萨奇3.0系统开发方案模式
Web3.0为用户提供了更多的创作和表达机会。在传统互联网时代,知识产权的保护和激励一直是一个难题
IPPswap交易所系统开发详细指南丨需求设计丨教程方案丨源码项目
Based on the development of the IPPSwap exchange exchange exchange bottom pool LP pledge mining system you mentioned, the following is an overview of its basic process and elements
|
供应链 算法 区块链
智能合约互助公排系统开发指南与方案
作为一种自动执行的协议,智能合约被嵌入在区块链计算机代码中
|
区块链
佛萨奇源码版丨佛萨奇2.0Metaforce系统开发功能方案/案例详细/方案项目/源码程序
  一条完整的区块链,是由众多分布式账本集合而成的一种数据链。那么随着其中某个账本的记录完成,区块也就随之生成。区块的生成过程也就可以理解为是交易的一个记账过程。但光有区块还是不够的,还得需要“链”将所有已有区块都连起来。那么所谓的“链”,就是时间戳技术以及某种智能合约。
|
存储 算法 区块链
链游项目系统开发(方案设计)丨DAPP链游系统开发(案例分析)/成熟技术/区块链游戏开发/源码说明
  在区块链中,每个块包含了一定数量的交易信息和该块的唯一标识符,同时还包含了前一个块的哈希值。这样的设计保证了区块之间的顺序和完整性,一旦一个块被添加到区块链中,它就不可更改。This makes blockchain a secure and trustworthy distributed ledger that can be used to record and verify various types of transactions.
|
安全 区块链 数据安全/隐私保护
佛萨奇智能合约系统开发2.0搭建技术
能钱包可以实现账户恢复(Argent,MYKEY)、交易金额限制(Argent,Monolith)、批量交易合并(MYKEY多target)等多种特性,切实帮助用户解决问题
佛萨奇智能合约系统开发2.0搭建技术
|
存储
佛萨奇2.0系统开发项目源码丨佛萨奇系统开发技术方案
佛萨奇2.0系统开发项目源码丨佛萨奇系统开发技术方案
355 0
|
存储 区块链
佛萨奇2.0马蹄莲智能合约开发原理丨MetaForce佛萨奇2.0马蹄莲智能合约DAPP系统开发成熟案例及源码部署
目前,DApp通常是指在以太坊或EOS上基于智能合约开发的相关应用。DAPP是Decentralized Application的缩写,即去中心化应用,也有人称为分布式应用。它被认为开启了区块链3.0时代。DAPP就是在底层区块链平台衍生的各种分布式应用,是区块链世界中的服务提供形式。
佛萨奇2.0马蹄莲智能合约开发原理丨MetaForce佛萨奇2.0马蹄莲智能合约DAPP系统开发成熟案例及源码部署
下一篇
无影云桌面