Solidity可支付函數(shù)使用示例詳解
引言
學(xué)習(xí)Solidity中可支付函數(shù)的相關(guān)知識(shí),了解它們?cè)谔幚硪蕴珟糯婵罘矫娴闹匾?,以及如何在智能合約中創(chuàng)建和使用它們。
通過(guò)本指南,您應(yīng)該能夠:
- 理解Solidity中可支付函數(shù)的目的和用法
- 學(xué)習(xí)如何向智能合約發(fā)送Ether
- 編寫(xiě)Solidity中的可支付函數(shù)
- 創(chuàng)建帶有條件的可撤銷(xiāo)可支付函數(shù)
- 在可支付函數(shù)中實(shí)現(xiàn)自定義邏輯
- 了解消息調(diào)用及其在以太坊虛擬機(jī)(EVM)中的相關(guān)性
Payable 函數(shù)
在Solidity中,可支付函數(shù)是一種能讓智能合約接受以太幣的函數(shù)。它們幫助開(kāi)發(fā)人員管理接收到的以太幣并在接收到時(shí)采取行動(dòng)。例如,一個(gè)簡(jiǎn)單的可支付函數(shù)可以為籌款活動(dòng)收集以太幣捐款。
以下是一個(gè)基本的代碼示例:
pragma solidity ^0.8.0; contract Fundraiser { function donate() external payable { // Ether is received and stored in the contract's balance // You can perform any other actions with the Ether received here - for example, sending it to some other address etc. } }
在這個(gè)例子中,當(dāng)調(diào)用donate
函數(shù)時(shí),它會(huì)接受捐贈(zèng)者發(fā)送的Ether并將其添加到合約的余額中。
關(guān)鍵字payable
允許某個(gè)人向合約發(fā)送ether并運(yùn)行代碼來(lái)處理此存款。
這段代碼可能會(huì)記錄事件,修改存儲(chǔ)以記錄存款,或者如果選擇這樣做,甚至可能撤銷(xiāo)交易。
當(dāng)開(kāi)發(fā)人員顯式標(biāo)記一個(gè)帶有可支付類(lèi)型的智能合約時(shí),他們表示“我希望將ether發(fā)送到這個(gè)函數(shù)”。要理解這為什么很重要,想象一下如果有人將ether發(fā)送到一個(gè)合約中,但開(kāi)發(fā)人員沒(méi)有編寫(xiě)代碼處理該事件,那將會(huì)有多糟糕。在那種情況下,ether可能會(huì)永久鎖定,或者無(wú)法被其預(yù)期的接收方提取。
如何向智能合約發(fā)送以太幣
發(fā)送以太幣是以太坊虛擬機(jī)(EVM)的本地功能。這與在EVM中進(jìn)行任何其他轉(zhuǎn)賬不同,該轉(zhuǎn)賬需要開(kāi)發(fā)人員編寫(xiě)自定義邏輯來(lái)處理轉(zhuǎn)賬(例如NFT或ERC20)。
當(dāng)有人向智能合約發(fā)送以太幣時(shí),他們通過(guò)交易本身的“value”字段進(jìn)行操作。讓我們看看JSON格式的交易內(nèi)容:
{ "to": "0x5baf84167cad405ce7b2e8458af73975f9489291", "value": "0xb1a2bc2ec50000", // 1 ether "data": "0xd0e30db0" // deposit() // ... other properties }
此交易將1個(gè)以太幣發(fā)送到地址0x5baf84167cad405ce7b2e8458af73975f9489291
。
如果此地址是一個(gè)智能合約,它將嘗試解析calldata(data)以確定此用戶試圖調(diào)用哪個(gè)智能合約函數(shù)(在這種情況下是deposit())。
根據(jù)函數(shù)支付或非支付的情況,將發(fā)生以下兩種情況之一:
- 如果函數(shù)是一個(gè)可支付函數(shù),那么它將運(yùn)行邏輯。
- 如果函數(shù)不可支付,則交易將恢復(fù)并返回資金,減去交易的燃?xì)獬杀尽?/li>
什么是 Solidity 可支付函數(shù)的示例?
這是一個(gè)使用Solidity的基本可支付函數(shù)示例,其中包括“deposit”函數(shù):
function deposit() payable external { // no need to write anything here! }
注意,在這種情況下,我們沒(méi)有在 deposit
函數(shù)主體中編寫(xiě)任何代碼。編寫(xiě)一個(gè)可支付的函數(shù)就足以接收以太幣,您可能不需要編寫(xiě)任何邏輯。
例如,如果這是一個(gè)可支付的智能合約,由慈善機(jī)構(gòu)控制,接受加密貨幣捐款,也許用戶只需調(diào)用 deposit
,慈善機(jī)構(gòu)最終就能夠?qū)⑦@些捐款提取到他們選擇的地址。在這種情況下,編寫(xiě)一個(gè) receive
函數(shù)可能更好:
receive() external payable { // this built-in function doesn't require any calldata, // it will get called if the data field is empty and // the value field is not empty. // this allows the smart contract to receive ether just like a // regular user account controlled by a private key would. }
什么是一個(gè)Solidity可支付函數(shù)的反轉(zhuǎn)示例?
一個(gè)可付款的智能合約函數(shù)可以回滾。這是一個(gè)可回滾的可付款函數(shù)示例,它使用兩個(gè)require語(yǔ)句來(lái)驗(yàn)證msg.value
和balances[msg.sender]
。
mapping(address => uint) balances; function deposit() payable external { // deposit sizes are restricted to 1 ether require(msg.value == 1 ether); // an address cannot deposit twice require(balances[msg.sender] == 0); balances[msg.sender] += msg.value; }
如果任何一個(gè)require
語(yǔ)句不為真,則交易將回滾并發(fā)送者將收回他們的資金。
為什么我們要在可支付函數(shù)中編寫(xiě)邏輯?
如果我們有一個(gè)智能合約,需要跟蹤誰(shuí)存入了哪些以太幣,我們可以在存儲(chǔ)中跟蹤它:
mapping(address => uint) balances; function deposit() payable external { // record the value sent // to the address that sent it balances[msg.sender] += msg.value; }
這里的msg.value
對(duì)應(yīng)著我們?cè)?ldquo;如何發(fā)送以太幣”部分看到的交易中編碼的value
字段。作為Solidity開(kāi)發(fā)人員,我們可以利用消息值來(lái)記錄存款并將其映射到該交易地址的某些內(nèi)部余額。
為什么叫做msg.value?
在以太坊虛擬機(jī)(EVM)中,與智能合約的交互被稱(chēng)為“消息調(diào)用”。這適用于用戶直接調(diào)用智能合約的情況,也適用于智能合約調(diào)用另一個(gè)智能合約的情況(內(nèi)部交易)。
可支付的Solidity函數(shù)
簡(jiǎn)而言之,一個(gè)可支付的函數(shù)是一個(gè)可以接收以太幣的函數(shù)。它為開(kāi)發(fā)者提供了回應(yīng)以太幣存款進(jìn)行記錄或任何其他必要邏輯的機(jī)會(huì)。
以上就是Solidity可支付函數(shù)使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Solidity可支付函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrap點(diǎn)擊下拉菜單項(xiàng)后顯示一個(gè)新的輸入框?qū)崿F(xiàn)代碼
這篇文章主要介紹了BootStrap點(diǎn)擊下拉菜單項(xiàng)后顯示一個(gè)新的輸入框?qū)崿F(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-05-05javascript用正則表達(dá)式過(guò)濾空格的實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇javascript用正則表達(dá)式過(guò)濾空格的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06細(xì)說(shuō)webpack6 Babel的使用詳解
這篇文章主要介紹了細(xì)說(shuō)webpack6 Babel的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09JSuggest自動(dòng)匹配下拉框使用方法(示例代碼)
本篇文章主要是對(duì)JSuggest自動(dòng)匹配下拉框使用方法進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12js前端加密庫(kù)Crypto-js進(jìn)行MD5/SHA256/BASE64/AES加解密的方法與示例
js加密解密可以使用crypto-js它可以進(jìn)行MD5、SHA-1、SHA-256、Base64、AES、DES、等算法和加密,這是一個(gè)對(duì)稱(chēng)加密的庫(kù),可以使用 AES、DES、但沒(méi)有rsa等非對(duì)稱(chēng)加密的方法2023-12-12淺談JavaScript中定義變量時(shí)有無(wú)var聲明的區(qū)別
這篇文章主要介紹了JavaScript中定義變量時(shí)有無(wú)var聲明的區(qū)別分析以及示例分享,需要的朋友可以參考下2014-08-08使用js和canvas實(shí)現(xiàn)時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了使用js和canvas實(shí)現(xiàn)時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09