摘要:接上一節(jié),繼續(xù)學(xué)習(xí)高級語法。添加語句,并且將后兩位數(shù)替換為添加參數(shù)四部署以太坊實現(xiàn)實現(xiàn)我們只用編譯和部署,就可以將這個合約部署到以太坊了。
接上一節(jié),繼續(xù)學(xué)習(xí)solidity高級語法。一、使用接口
繼續(xù)前面上一節(jié) NumberInterface 的例子,我們既然將接口定義為:
contract NumberInterface { function getNum(address _myAddress) public view returns (uint); }
我們可以在合約中這樣使用:
contract MyContract { address NumberInterfaceAddress = 0xab38...; // ^ 這是FavoriteNumber合約在以太坊上的地址 NumberInterface numberContract = NumberInterface(NumberInterfaceAddress); // 現(xiàn)在變量 `numberContract` 指向另一個合約對象 function someFunction() public { // 現(xiàn)在我們可以調(diào)用在那個合約中聲明的 `getNum`函數(shù): uint num = numberContract.getNum(msg.sender); // ...在這兒使用 `num`變量做些什么 } }
通過這種方式,只要將您合約的可見性設(shè)置為public(公共)或external(外部),它們就可以與以太坊區(qū)塊鏈上的任何其他合約進(jìn)行交互。
實戰(zhàn)演練我們來建個自己的合約去讀取另一個智能合約-- CryptoKitties 的內(nèi)容吧!
1、我已經(jīng)將代碼中 CryptoKitties 合約的地址保存在一個名為 ckAddress 的變量中。在下一行中,請創(chuàng)建一個名為 kittyContract 的 KittyInterface,并用 ckAddress 為它初始化 —— 就像我們?yōu)?numberContract 所做的一樣。
zombiefeeding.sol
pragma solidity ^0.4.19; import "./zombiefactory.sol"; contract KittyInterface { function getKitty(uint256 _id) external view returns ( bool isGestating, bool isReady, uint256 cooldownIndex, uint256 nextActionAt, uint256 siringWithId, uint256 birthTime, uint256 matronId, uint256 sireId, uint256 generation, uint256 genes ); } contract ZombieFeeding is ZombieFactory { address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d; // Initialize kittyContract here using `ckAddress` from above KittyInterface kittyContract = KittyInterface(ckAddress); function feedAndMultiply(uint _zombieId, uint _targetDna) public { require(msg.sender == zombieToOwner[_zombieId]); Zombie storage myZombie = zombies[_zombieId]; _targetDna = _targetDna % dnaModulus; uint newDna = (myZombie.dna + _targetDna) / 2; _createZombie("NoName", newDna); } }二、處理多返回值
getKitty 是我們所看到的第一個返回多個值的函數(shù)。我們來看看是如何處理的:
unction multipleReturns() internal returns(uint a, uint b, uint c) { return (1, 2, 3); } function processMultipleReturns() external { uint a; uint b; uint c; // 這樣來做批量賦值: (a, b, c) = multipleReturns(); } // 或者如果我們只想返回其中一個變量: function getLastReturnValue() external { uint c; // 可以對其他字段留空: (,,c) = multipleReturns(); }實戰(zhàn)演練
是時候與 CryptoKitties 合約交互起來了!
我們來定義一個函數(shù),從 kitty 合約中獲取它的基因:
1、創(chuàng)建一個名為 feedOnKitty 的函數(shù)。它需要2個 uint 類型的參數(shù),_zombieId 和_kittyId ,這是一個 public 類型的函數(shù)。
2、函數(shù)首先要聲明一個名為 kittyDna 的 uint。
注意:在我們的 KittyInterface 中,genes 是一個 uint256 類型的變量,但是如果你記得,我們在第一課中提到過,uint 是 uint256 的別名,也就是說它們是一回事。
3、這個函數(shù)接下來調(diào)用 kittyContract.getKitty函數(shù), 傳入 _kittyId ,將返回的 genes 存儲在 kittyDna 中。記住 —— getKitty 會返回一大堆變量。 (確切地說10個 - 我已經(jīng)為你數(shù)過了,不錯吧?。?。但是我們只關(guān)心最后一個-- genes。數(shù)逗號的時候小心點(diǎn)哦!
4、最后,函數(shù)調(diào)用了 feedAndMultiply ,并傳入了 _zombieId 和 kittyDna 兩個參數(shù)。
zombiefeeding.sol
pragma solidity ^0.4.19; import "./zombiefactory.sol"; contract KittyInterface { function getKitty(uint256 _id) external view returns ( bool isGestating, bool isReady, uint256 cooldownIndex, uint256 nextActionAt, uint256 siringWithId, uint256 birthTime, uint256 matronId, uint256 sireId, uint256 generation, uint256 genes ); } contract ZombieFeeding is ZombieFactory { address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d; KittyInterface kittyContract = KittyInterface(ckAddress); function feedAndMultiply(uint _zombieId, uint _targetDna) public { require(msg.sender == zombieToOwner[_zombieId]); Zombie storage myZombie = zombies[_zombieId]; _targetDna = _targetDna % dnaModulus; uint newDna = (myZombie.dna + _targetDna) / 2; _createZombie("NoName", newDna); } // define function here function feedOnKitty(uint _zombieId, uint _kittyId) public { uint kittyDna; // 聲明一個參數(shù) // 多參數(shù)返回,前邊不需要的可以用空格,只獲取需要的返回參數(shù) (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId); feedAndMultiply(_zombieId, kittyDna); } }三、if語句用法
我們的功能邏輯主體已經(jīng)完成了...現(xiàn)在讓我們來添一個獎勵功能吧。
這樣吧,給從小貓制造出的僵尸添加些特征,以顯示他們是貓僵尸。
要做到這一點(diǎn),咱們在新僵尸的DNA中添加一些特殊的小貓代碼。
還記得嗎,第一課中我們提到,我們目前只使用16位DNA的前12位數(shù)來指定僵尸的外觀。所以現(xiàn)在我們可以使用最后2個數(shù)字來處理“特殊”的特征。
這樣吧,把貓僵尸DNA的最后兩個數(shù)字設(shè)定為99(因為貓有9條命)。所以在我們這么來寫代碼:如果這個僵尸是一只貓變來的,就將它DNA的最后兩位數(shù)字設(shè)置為99。
if 語句if語句的語法在 Solidity 中,與在 JavaScript 中差不多:
function eatBLT(string sandwich) public { // 看清楚了,當(dāng)我們比較字符串的時候,需要比較他們的 keccak256 哈希碼 if (keccak256(sandwich) == keccak256("BLT")) { eat(); } }實戰(zhàn)演練
讓我們在我們的僵尸代碼中實現(xiàn)小貓的基因。
1、首先,我們修改下 feedAndMultiply 函數(shù)的定義,給它傳入第三個參數(shù):一條名為 _species 的字符串。
2、接下來,在我們計算出新的僵尸的DNA之后,添加一個 if 語句來比較 _species 和字符串 "kitty" 的 keccak256 哈希值。
3、在 if 語句中,我們用 99 替換了新僵尸DNA的最后兩位數(shù)字。可以這么做:newDna = newDna - newDna%100 + 99;。
解釋:假設(shè) newDna 是 334455。那么 newDna%100 是 55,所以 newDna - newDna%100 得到 334400。最后加上 99 可得到 334499。
4、最后,我們修改了 feedOnKitty 中的函數(shù)調(diào)用。當(dāng)它調(diào)用 feedAndMultiply 時,增加 “kitty” 作為最后一個參數(shù)。
zombiefeeding.sol
pragma solidity ^0.4.19; import "./zombiefactory.sol"; contract KittyInterface { function getKitty(uint256 _id) external view returns ( bool isGestating, bool isReady, uint256 cooldownIndex, uint256 nextActionAt, uint256 siringWithId, uint256 birthTime, uint256 matronId, uint256 sireId, uint256 generation, uint256 genes ); } contract ZombieFeeding is ZombieFactory { address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d; KittyInterface kittyContract = KittyInterface(ckAddress); // Modify function definition here: function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) public { require(msg.sender == zombieToOwner[_zombieId]); Zombie storage myZombie = zombies[_zombieId]; _targetDna = _targetDna % dnaModulus; uint newDna = (myZombie.dna + _targetDna) / 2; // Add an if statement here,添加if語句,并且將后兩位數(shù)替換為99 if (keccak256(_species) == keccak256("kitty")) { newDna = newDna - newDna % 100 + 99; } _createZombie("NoName", newDna); } function feedOnKitty(uint _zombieId, uint _kittyId) public { uint kittyDna; (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId); // And modify function call here:添加參數(shù) feedAndMultiply(_zombieId, kittyDna, "kitty"); } }四、部署以太坊實現(xiàn) javaScript 實現(xiàn)
我們只用編譯和部署 ZombieFeeding,就可以將這個合約部署到以太坊了。我們最終完成的這個合約繼承自 ZombieFactory,因此它可以訪問自己和父輩合約中的所有 public 方法。
我們來看一個與我們的剛部署的合約進(jìn)行交互的例子, 這個例子使用了 JavaScript 和 web3.js:
var abi = /* abi generated by the compiler */ var ZombieFeedingContract = web3.eth.contract(abi) var contractAddress = /* our contract address on Ethereum after deploying */ var ZombieFeeding = ZombieFeedingContract.at(contractAddress) // 假設(shè)我們有我們的僵尸ID和要攻擊的貓咪ID let zombieId = 1; let kittyId = 1; // 要拿到貓咪的DNA,我們需要調(diào)用它的API。這些數(shù)據(jù)保存在它們的服務(wù)器上而不是區(qū)塊鏈上。 // 如果一切都在區(qū)塊鏈上,我們就不用擔(dān)心它們的服務(wù)器掛了,或者它們修改了API, // 或者因為不喜歡我們的僵尸游戲而封殺了我們 let apiUrl = "https://api.cryptokitties.co/kitties/" + kittyId $.get(apiUrl, function(data) { let imgUrl = data.image_url // 一些顯示圖片的代碼 }) // 當(dāng)用戶點(diǎn)擊一只貓咪的時候: $(".kittyImage").click(function(e) { // 調(diào)用我們合約的 `feedOnKitty` 函數(shù) ZombieFeeding.feedOnKitty(zombieId, kittyId) }) // 偵聽來自我們合約的新僵尸事件好來處理 ZombieFactory.NewZombie(function(error, result) { if (error) return // 這個函數(shù)用來顯示僵尸: generateZombie(result.zombieId, result.name, result.dna) })
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/24136.html
摘要:以太坊開發(fā)高級語言學(xué)習(xí)。地址以太坊區(qū)塊鏈由賬戶組成,你可以把它想象成銀行賬戶。使用很安全,因為它具有以太坊區(qū)塊鏈的安全保障除非竊取與以太坊地址相關(guān)聯(lián)的私鑰,否則是沒有辦法修改其他人的數(shù)據(jù)的。 以太坊開發(fā)高級語言學(xué)習(xí)。 一、映射(Mapping)和地址(Address) 我們通過給數(shù)據(jù)庫中的僵尸指定主人, 來支持多玩家模式。 如此一來,我們需要引入2個新的數(shù)據(jù)類型:mapping(映射)...
摘要:引言給迷失在如何學(xué)習(xí)區(qū)塊鏈技術(shù)的同學(xué)一個指引,區(qū)塊鏈技術(shù)是隨比特幣誕生,因此要搞明白區(qū)塊鏈技術(shù),應(yīng)該先了解下比特幣。但區(qū)塊鏈技術(shù)不單應(yīng)用于比特幣,還有非常多的現(xiàn)實應(yīng)用場景,想做區(qū)塊鏈應(yīng)用開發(fā),可進(jìn)一步閱讀以太坊系列。 本文始發(fā)于深入淺出區(qū)塊鏈社區(qū), 原文:區(qū)塊鏈技術(shù)學(xué)習(xí)指引 原文已更新,請讀者前往原文閱讀 本章的文章越來越多,本文是一個索引帖,方便找到自己感興趣的文章,你也可以使用左側(cè)...
摘要:原文發(fā)表于以太坊智能合約開發(fā)第一篇對語法的支持最近在研究以太坊智能合約的開發(fā)。是一種語法類似的高級語言,它被設(shè)計成以編譯的方式生成以太坊虛擬機(jī)代碼。 原文發(fā)表于:以太坊智能合約開發(fā)第一篇:IDE對solidity語法的支持 最近在研究以太坊智能合約的開發(fā)。隨著研究的深入,準(zhǔn)備寫一個系列教程,將我的實際經(jīng)驗與大家分享,供大家參考借鑒。 solidity是什么? 以太坊官方推薦使用Sol...
摘要:接上篇文章,這里繼續(xù)學(xué)習(xí)高級理論。實戰(zhàn)演練我們來寫一個返回某玩家的整個僵尸軍團(tuán)的函數(shù)。但這樣每做一筆交易,都會改變僵尸軍團(tuán)的秩序。在這里開始五可支付截至目前,我們只接觸到很少的函數(shù)修飾符。 接上篇文章,這里繼續(xù)學(xué)習(xí)Solidity高級理論。 一、深入函數(shù)修飾符 接下來,我們將添加一些輔助方法。我們?yōu)槟鷦?chuàng)建了一個名為 zombiehelper.sol 的新文件,并且將 zombiefee...
摘要:如果當(dāng)前在以太坊上有大量掛起事務(wù)或者用戶發(fā)送了過低的價格,我們的事務(wù)可能需要等待數(shù)個區(qū)塊才能被包含進(jìn)去,往往可能花費(fèi)數(shù)分鐘。 接上篇 Web3.js,這節(jié)課繼續(xù)學(xué)習(xí)Web3.js 的相關(guān)知識。 一、發(fā)送事務(wù) 這下我們的界面能檢測用戶的 MetaMask 賬戶,并自動在首頁顯示它們的僵尸大軍了,有沒有很棒? 現(xiàn)在我們來看看用 send 函數(shù)來修改我們智能合約里面的數(shù)據(jù)。 相對 call...
閱讀 2043·2023-04-25 23:30
閱讀 1466·2021-11-24 10:18
閱讀 3101·2021-10-09 09:54
閱讀 2026·2021-10-08 10:05
閱讀 3450·2021-09-23 11:21
閱讀 3173·2019-08-30 15:52
閱讀 1570·2019-08-30 13:05
閱讀 1069·2019-08-30 13:02