Solidity智能合约开发入门:从基础到实践掌握DApp开发
imtoken钱包官网app下载 2025年4月23日 13:10:07 imtoken钱包官网app下载 14
contract SimpleStorage { uint storedData; function set(uint x) { storedData = x; } function get() constant returns (uint retVal) { return storedData; } }
状态变量声明
在以太坊合约里,有“uint storedData;”这样的一行代码。这行代码的作用是声明了一个状态变量。这个变量名叫 storedData 。其类型为 uint ,即 256bits 的无符号整数。它就好像数据库中的一个存储单元。我们能够像管理数据库那样,通过调用函数来对它进行查询操作以及进行修改。不使用 this 前缀也能直接访问这个状态变量,并且使用过程很便捷。
这一声明看似基础。它开启了合约数据存储的进程,为后续实现更多功能奠定了基础。参与合约的人,不论在世界的哪个角落,都能借助它来存储数字。
合约功能局限
当前这个合约能力有局限,原因是受以太坊基础设施制约,能做的事不多。它只允许任何人储存一个数字,且世界上任何人都能存取这个数字,但缺少可靠保护机制。任何人都可调用 set 方法设置不同数字,把发布的数字覆盖掉,这让数据安全性成大问题。
contract Coin { //关键字“public”使变量能从合约外部访问。 address public minter; mapping (address => uint) public balances; //事件让轻客户端能高效的对变化做出反应。 event Sent(address from, address to, uint amount); //这个构造函数的代码仅仅只在合约创建的时候被运行。 function Coin() { minter = msg.sender; } function mint(address receiver, uint amount) { if (msg.sender != minter) return; balances[receiver] += amount; } function send(address receiver, uint amount) { if (balances[msg.sender] < amount) return; balances[msg.sender] -= amount; balances[receiver] += amount; Sent(msg.sender, receiver, amount); } }
在实际应用中,如果这个数据是关键的,那么它被随意覆盖就可能导致重要信息丢失,接着会引发严重的后果。很多开发者都希望能有更好的安全方案来处理这个问题。
address public minter;`
地址状态变量
代码中声明了一种状态变量,其类型为 address 且可公开访问。public 这个关键字具有很大的作用,它能自动为被修饰的状态变量生成访问函数。若没有这个关键字,变量就无法被其他合约访问,并且编译器会报错。这种因 public 关键字而产生的便利,让合约之间的交互变得相对简单了。
开发由多个合约协同工作的项目时,这种特性可以自动生成访问函数,这样就节省了很多开发时间和精力,让开发者能够更专心地编写核心逻辑。
function minter() returns (address) { return minter; }
复杂状态变量mapping
下一行代码创建了一个更复杂的 public 状态变量,此变量的类型为 mapping。它的作用类似于哈希表,即每个可能的 key 所对应的 value 被虚拟初始化为全 0。需注意,这个类比并非十分精确,我们无法获取它所有的 key 以及 value 的链表。最好是维护一个链表或者采用其他高级数据类型。
mapping (address => uint) public balances;
在存储大规模数据以及进行查找工作的时候,mapping 能够发挥良好的作用。如果没有妥善处理链表问题,就会给数据的全面管理带来一定的困难,从而对开发效率和合约性能产生影响。
事件监听与参数
客户端应用能够以较低的开销来对区块链触发的事件进行监听。服务端应用同样可以做到这一点。当事件被触发时,监听者可以接收到像 from、to、value 这样的参数值,这对于跟踪交易是很方便的。我们可以运用相关代码来监听事件,并且要留意在客户端调用自动生成的 balances 函数。
在实际交易场景中,开发者能够通过对这些事件进行监听,进而实时了解交易的动态情况。同时,用户也可以这样做,他们能够及时察觉到异常状况。这样做的目的是保障交易的安全以及让交易顺利开展。
function balances(address _account) returns (uint balance) { return balances[_account]; }
构造函数与全局变量
event Sent(address from, address to, uint value);
构造函数会在合约创建时运行,而在合约创建之后就不能被调用了。有一些神奇的全局变量,如 msg、tx 和 block,它们包含了区块链的属性,合约代码可以对其进行访问。mint 和 send 这两个函数能够让合约发挥功能。如果不是合约创建者去调用 mint 函数,就不会有任何反应。
在创建代币合约时,构造函数会对一些关键参数进行初始化操作。全局变量有助于合约与区块链进行更良好的交互。如果有人因不小心而误操作调用了 mint,系统会保持原本的状态,以此避免不必要的错误发生。
最后来问问大家,在以太坊合约里,对于这些状态变量以及功能函数的运用情况,在实际进行开发的过程中,你们都碰到过哪些问题?欢迎大家在评论区留言进行分享,并且也别忘记点赞和分享本文。
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)); } }