摘要:接上一節,繼續學習高級語法。添加語句,并且將后兩位數替換為添加參數四部署以太坊實現實現我們只用編譯和部署,就可以將這個合約部署到以太坊了。
接上一節,繼續學習solidity高級語法。一、使用接口
繼續前面上一節 NumberInterface 的例子,我們既然將接口定義為:
contract NumberInterface { function getNum(address _myAddress) public view returns (uint); }
我們可以在合約中這樣使用:
contract MyContract { address NumberInterfaceAddress = 0xab38...; // ^ 這是FavoriteNumber合約在以太坊上的地址 NumberInterface numberContract = NumberInterface(NumberInterfaceAddress); // 現在變量 `numberContract` 指向另一個合約對象 function someFunction() public { // 現在我們可以調用在那個合約中聲明的 `getNum`函數: uint num = numberContract.getNum(msg.sender); // ...在這兒使用 `num`變量做些什么 } }
通過這種方式,只要將您合約的可見性設置為public(公共)或external(外部),它們就可以與以太坊區塊鏈上的任何其他合約進行交互。
實戰演練我們來建個自己的合約去讀取另一個智能合約-- CryptoKitties 的內容吧!
1、我已經將代碼中 CryptoKitties 合約的地址保存在一個名為 ckAddress 的變量中。在下一行中,請創建一個名為 kittyContract 的 KittyInterface,并用 ckAddress 為它初始化 —— 就像我們為 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 是我們所看到的第一個返回多個值的函數。我們來看看是如何處理的:
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(); }實戰演練
是時候與 CryptoKitties 合約交互起來了!
我們來定義一個函數,從 kitty 合約中獲取它的基因:
1、創建一個名為 feedOnKitty 的函數。它需要2個 uint 類型的參數,_zombieId 和_kittyId ,這是一個 public 類型的函數。
2、函數首先要聲明一個名為 kittyDna 的 uint。
注意:在我們的 KittyInterface 中,genes 是一個 uint256 類型的變量,但是如果你記得,我們在第一課中提到過,uint 是 uint256 的別名,也就是說它們是一回事。
3、這個函數接下來調用 kittyContract.getKitty函數, 傳入 _kittyId ,將返回的 genes 存儲在 kittyDna 中。記住 —— getKitty 會返回一大堆變量。 (確切地說10個 - 我已經為你數過了,不錯吧!)。但是我們只關心最后一個-- genes。數逗號的時候小心點哦!
4、最后,函數調用了 feedAndMultiply ,并傳入了 _zombieId 和 kittyDna 兩個參數。
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; // 聲明一個參數 // 多參數返回,前邊不需要的可以用空格,只獲取需要的返回參數 (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId); feedAndMultiply(_zombieId, kittyDna); } }三、if語句用法
我們的功能邏輯主體已經完成了...現在讓我們來添一個獎勵功能吧。
這樣吧,給從小貓制造出的僵尸添加些特征,以顯示他們是貓僵尸。
要做到這一點,咱們在新僵尸的DNA中添加一些特殊的小貓代碼。
還記得嗎,第一課中我們提到,我們目前只使用16位DNA的前12位數來指定僵尸的外觀。所以現在我們可以使用最后2個數字來處理“特殊”的特征。
這樣吧,把貓僵尸DNA的最后兩個數字設定為99(因為貓有9條命)。所以在我們這么來寫代碼:如果這個僵尸是一只貓變來的,就將它DNA的最后兩位數字設置為99。
if 語句if語句的語法在 Solidity 中,與在 JavaScript 中差不多:
function eatBLT(string sandwich) public { // 看清楚了,當我們比較字符串的時候,需要比較他們的 keccak256 哈希碼 if (keccak256(sandwich) == keccak256("BLT")) { eat(); } }實戰演練
讓我們在我們的僵尸代碼中實現小貓的基因。
1、首先,我們修改下 feedAndMultiply 函數的定義,給它傳入第三個參數:一條名為 _species 的字符串。
2、接下來,在我們計算出新的僵尸的DNA之后,添加一個 if 語句來比較 _species 和字符串 "kitty" 的 keccak256 哈希值。
3、在 if 語句中,我們用 99 替換了新僵尸DNA的最后兩位數字。可以這么做:newDna = newDna - newDna%100 + 99;。
解釋:假設 newDna 是 334455。那么 newDna%100 是 55,所以 newDna - newDna%100 得到 334400。最后加上 99 可得到 334499。
4、最后,我們修改了 feedOnKitty 中的函數調用。當它調用 feedAndMultiply 時,增加 “kitty” 作為最后一個參數。
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語句,并且將后兩位數替換為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:添加參數 feedAndMultiply(_zombieId, kittyDna, "kitty"); } }四、部署以太坊實現 javaScript 實現
我們只用編譯和部署 ZombieFeeding,就可以將這個合約部署到以太坊了。我們最終完成的這個合約繼承自 ZombieFactory,因此它可以訪問自己和父輩合約中的所有 public 方法。
我們來看一個與我們的剛部署的合約進行交互的例子, 這個例子使用了 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) // 假設我們有我們的僵尸ID和要攻擊的貓咪ID let zombieId = 1; let kittyId = 1; // 要拿到貓咪的DNA,我們需要調用它的API。這些數據保存在它們的服務器上而不是區塊鏈上。 // 如果一切都在區塊鏈上,我們就不用擔心它們的服務器掛了,或者它們修改了API, // 或者因為不喜歡我們的僵尸游戲而封殺了我們 let apiUrl = "https://api.cryptokitties.co/kitties/" + kittyId $.get(apiUrl, function(data) { let imgUrl = data.image_url // 一些顯示圖片的代碼 }) // 當用戶點擊一只貓咪的時候: $(".kittyImage").click(function(e) { // 調用我們合約的 `feedOnKitty` 函數 ZombieFeeding.feedOnKitty(zombieId, kittyId) }) // 偵聽來自我們合約的新僵尸事件好來處理 ZombieFactory.NewZombie(function(error, result) { if (error) return // 這個函數用來顯示僵尸: generateZombie(result.zombieId, result.name, result.dna) })
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/24136.html
摘要:以太坊開發高級語言學習。地址以太坊區塊鏈由賬戶組成,你可以把它想象成銀行賬戶。使用很安全,因為它具有以太坊區塊鏈的安全保障除非竊取與以太坊地址相關聯的私鑰,否則是沒有辦法修改其他人的數據的。 以太坊開發高級語言學習。 一、映射(Mapping)和地址(Address) 我們通過給數據庫中的僵尸指定主人, 來支持多玩家模式。 如此一來,我們需要引入2個新的數據類型:mapping(映射)...
摘要:原文發表于以太坊智能合約開發第一篇對語法的支持最近在研究以太坊智能合約的開發。是一種語法類似的高級語言,它被設計成以編譯的方式生成以太坊虛擬機代碼。 原文發表于:以太坊智能合約開發第一篇:IDE對solidity語法的支持 最近在研究以太坊智能合約的開發。隨著研究的深入,準備寫一個系列教程,將我的實際經驗與大家分享,供大家參考借鑒。 solidity是什么? 以太坊官方推薦使用Sol...
摘要:接上篇文章,這里繼續學習高級理論。實戰演練我們來寫一個返回某玩家的整個僵尸軍團的函數。但這樣每做一筆交易,都會改變僵尸軍團的秩序。在這里開始五可支付截至目前,我們只接觸到很少的函數修飾符。 接上篇文章,這里繼續學習Solidity高級理論。 一、深入函數修飾符 接下來,我們將添加一些輔助方法。我們為您創建了一個名為 zombiehelper.sol 的新文件,并且將 zombiefee...
摘要:如果當前在以太坊上有大量掛起事務或者用戶發送了過低的價格,我們的事務可能需要等待數個區塊才能被包含進去,往往可能花費數分鐘。 接上篇 Web3.js,這節課繼續學習Web3.js 的相關知識。 一、發送事務 這下我們的界面能檢測用戶的 MetaMask 賬戶,并自動在首頁顯示它們的僵尸大軍了,有沒有很棒? 現在我們來看看用 send 函數來修改我們智能合約里面的數據。 相對 call...
閱讀 2022·2023-04-25 23:30
閱讀 1452·2021-11-24 10:18
閱讀 3069·2021-10-09 09:54
閱讀 2017·2021-10-08 10:05
閱讀 3431·2021-09-23 11:21
閱讀 3161·2019-08-30 15:52
閱讀 1560·2019-08-30 13:05
閱讀 1056·2019-08-30 13:02