今天卜問的是Keep Network(KEEP幣、tBTC) 卜問Keep Network一年之內的發展如何?卜得損上九臨 損上九,弗損,益之,无咎,貞吉。利有攸往,得臣无家。 [變卦臨]上六,敦臨,吉,无咎。 Keep Network主要目標是建立資產跨鏈協議,目前主要的方案就是和BTC價格定錨的ERC20代幣tBTC,之前也有介紹過和BTC定錨的WBTC(https://noise.cash/post/jpjq7vnhn05wx ),不過WBTC主要做法是中心化託管錨定,而Keep Network做的則是以去中心化非託管的機制在運作,而這裡的變卦爻辭「敦臨」便具有「敦厚治理、非一手掌控」的性質 因為本卦是損卦,又有爻辭「敦臨」,所以其運作系統可能不太嚴謹,這一年短期內可能會出現一些小問題,需要開發團隊好好修復,不過從長期來看還算是有不錯的利益,從爻辭「利有攸往,得臣无家」可以得知作為工具來說,Keep Network算是運作得不錯 2022年7月29日3時 -------------------------- 來回顧一下狗狗幣和柴犬幣的占卜結果: https://noise.cash/post/69850w7s23r65 https://noise.cash/post/w843qvxsmpkgr 最近看到這則新聞: 迷因幣話題退燒!狗狗幣、柴犬幣 Google 搜尋熱度降至1年多來最低點 https://www.blocktempo.com/interest-in-dogecoin-and-shiba-inu-on-google-falls-to-the-lowest-level-in-over-a-year/ 狗狗幣如預測一樣,熱度往下降了不少,而且背後支持的馬斯克喊話的影響力也沒那麼強了,而柴犬幣雖然之前弄出不少花樣,不過還是沒辦法反抗迷因幣話題退燒的頹勢
@vcckvvOnNoiseApp
Joined 21 September 2022 · 356 posts
https://read.cash/@vcckvv
120 KT
0 KT received · 0 KT given
Posts
依照預告,這次要利用區塊鏈功能來打造一個Web3線上聊天室,沒看過之前智能合約的介紹的話可以先去看一下之前的文章: (1) https://noise.cash/post/jgmg36rhn05wx (2) https://noise.cash/post/r6v7389f5k67z (3) https://noise.cash/post/66xr32vf23r65 (4) https://noise.cash/post/n4qngmpb0n34w (5) https://noise.cash/post/66484zga23r65 Web3線上聊天室基本上就是全部的文章都會上鏈,不過這次寫的聊天室功能很陽春,沒有修改或刪除等功能,唯一有的額外功能是可以設定使用者帳戶的名字,比起位址要更好認出是誰 那麼就直接先來體驗一下:https://vcckvv.github.io/SmartContract/CoolChat/ 使用的合約在這裡:https://goerli.etherscan.io/address/0xc9e45809aaca0c8aa485d1bd558276e03e9451f6#code 這裡簡單介紹一下使用的方法: 1.沒有MetaMask錢包的人要安裝MetaMask錢包瀏覽器外掛,安裝完記得要開啟起來 2.因為發文章或設定名字都需要goerli測試鏈的gas費,所以要先到goerli的水龍頭網站領取代幣:https://goerlifaucet.com/ 3.接下來打開CoolChat的網頁,會自動跳出MetaMask視窗要求和錢包帳戶連線以及切換到goerli測試鏈 4.然後設定帳戶名字,在「名字」的文字輸入框中輸入想要的名字,設定上最多30個文字,且不能設成別人已經設定的名字,接下來按下「設定名字」的按鈕,MetaMask會跳出交易簽署視窗,confirm後等待上鏈完成就算設定成功,goerli上鏈時間一般在半分鐘內就會完成,且MetaMask會自動跳出成功的通知 稍微提醒一下,在簽署交易時檢查所在鏈、費用、和合約內容算是蠻重要的事,大家最好養成習慣 5.要發文也是相同的做法,在「輸入文章內容」下面的文字輸入框中輸入文章內容,設定上最多1000個文字,接下來按下「設定名字」的按鈕,MetaMask會跳出交易簽署視窗,confirm後等待上鏈完成就算發文成功,此時頁面會自動更新,可以看到自己的文章顯示在列表的上面 注意簽署交易的速度不要太快,要等上一筆的交易上鏈後再發,否則一般都會導致交易失敗,這可能跟交易的nonce數的某些安全限制有關 6.設定上每頁最多顯示20篇文章,文章列表最下面可以選擇要看的頁面,點選後會自動捲動頁面到最上面,選擇不同頁面時不會更新總文章數,所以不會點一點就因為新文章的出現而顯示出不連續的文章編號,如果要看更新的文章只要重新整理頁面就可以了 7.這個聊天室寫下的東西都會永久記錄到goerli測試鏈,所以除非goerli測試鏈被官方停掉,都不需要擔心資料消失的問題,網頁本身實際上也只是靜態網頁,複製放到其他伺服器上也能馬上運作 接下來看一下完整的合約程式碼: https://github.com/vcckvv/SmartContract/blob/gh-pages/CoolChat/CoolChat.sol --------------------------------------- pragma solidity ^0.8.0; // SPDX-License-Identifier: CC-BY-SA-4.0 contract CoolChat { address founderAddr; mapping (address => string) addrNameMap; mapping (string => bool) nameUseMap; address[] writerArray; string[] writerNameArray; uint256[] timeArray; string[] articleArray; constructor() { founderAddr = msg.sender; } function getArticleCount() public view returns (uint256 index) { return articleArray.length; } function getArticle(uint256 index) public view returns (address, string memory, uint256, string memory) { require(index<articleArray.length); return (writerArray[index], writerNameArray[index], timeArray[index], articleArray[index]); } function getArticles(uint256 index, uint256 count) public view returns (address[] memory, string[] memory, uint256[] memory, string[] memory) { require(count>=1); require(index+count-1<articleArray.length); address[] memory outWriterArray=new address[](count); string[] memory outWriterNameArray=new string[](count); uint256[] memory outTimeArray=new uint256[](count); string[] memory outArticleArray=new string[](count); for(uint i=0; i<count; i++){ outWriterArray[i]=writerArray[index+i]; outWriterNameArray[i]=writerNameArray[index+i]; outTimeArray[i]=timeArray[index+i]; outArticleArray[i]=articleArray[index+i]; } return (outWriterArray, outWriterNameArray, outTimeArray, outArticleArray); } function addArticle(string memory str) public { require(bytes(str).length>0 && bytes(str).length<=3000);//utf8中文字最多1000字 writerArray.push(msg.sender); writerNameArray.push(addrNameMap[msg.sender]); timeArray.push(block.timestamp); articleArray.push(str); } function testMassArticle(uint256 num) public { require(msg.sender==founderAddr); string memory name=addrNameMap[msg.sender]; string[4] memory strArray=["0", "1", "2", "3"]; for(uint i=0; i<num; i++){ writerArray.push(msg.sender); writerNameArray.push(name); timeArray.push(block.timestamp); articleArray.push(strArray[i%4]); } } function isUsedName(string memory name) public view returns (bool) { return nameUseMap[name]; } function getWriterName(address addr) public view returns (string memory) { return addrNameMap[addr]; } function setWriterName(string memory name) public { require(bytes(name).length>0 && bytes(name).length<=90);//utf8中文字最多30字 require(nameUseMap[name]==false); string memory oldName=addrNameMap[msg.sender]; if(bytes(oldName).length!=0){ nameUseMap[oldName]=false; } nameUseMap[name]=true; addrNameMap[msg.sender]=name; } } --------------------------------------- (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) --------------------------------------- 解說: pragma solidity ^0.8.0; // SPDX-License-Identifier: CC-BY-SA-4.0 這次換到版本0.8.0主要是因為會用到新的版本的功能,舊版的預設上沒辦法回傳陣列形式的變數,所以就改到了新版 SPDX-License-Identifier這段雖然是註解,但是沒加入的話會產生警告,基本上這個功能就是用來宣告版權,如果有其他偏好的版權的話可以參考這個網頁的代碼來設定:https://spdx.org/licenses/ --------------------------------------- address founderAddr; 用來存放建立合約者的帳戶位址,設定這個之後可以讓某些函數只能讓建立合約者來操作 --------------------------------------- mapping (address => string) addrNameMap; mapping (string => bool) nameUseMap; 映射的資料結構,就是給一個key值然後取出相應的資料的這樣的資料結構,不過使用上和C++的map的功能差很多,這個沒辦法從小到大一筆一筆資料列出來,如果想要更複雜的操作的資料結構都需要自己寫 addrNameMap用來儲存帳戶位址的名字,nameUseMap則用來判斷名字是不是已經有人使用 --------------------------------------- address[] writerArray; string[] writerNameArray; uint256[] timeArray; string[] articleArray; 文章的資料以陣列的形式來呈現,而且是把三種資料分開存放:寫的人的帳戶位址、寫的人設定的名字、文章時間、文章內容 其中文章時間是以timestamp形式來存放,所以是uint256,在javascript中使用以下的方式來轉換成一般的時間格式: let time = new Date(timestamp * 1000); let year = time.getFullYear(); let month = time.getMonth()+1; let date = time.getDate(); let hour = time.getHours(); let min = time.getMinutes(); let sec = time.getSeconds(); --------------------------------------- constructor() { founderAddr = msg.sender; } 如之前所述,constructor()只有在建立合約時才會呼叫,所以這裡的msg.sender就是建立合約者的帳戶位址 --------------------------------------- function getArticleCount() public view returns (uint256 index) { return articleArray.length; } 取得目前的總文章數,articleArray.length就是文章陣列的資料數目 --------------------------------------- function getArticle(uint256 index) public view returns (address, string memory, uint256, string memory) { require(index<articleArray.length); return (writerArray[index], writerNameArray[index], timeArray[index], articleArray[index]); } 取得一篇文章的資料,原本只寫了這個函數來讀取文章,不過實際測試時發現一篇一篇讀取的速度太慢了,所以下面又寫了一次讀取多個文章的函數getArticles 這裡用到了require()來檢查輸入參數是不是有問題,如果在require()中檢查出了問題就會讓這筆合約互動交易失效,之前做的所有更動都會復原,要注意如果是寫入性質的函數,一旦交易上鏈,那麼如果中途檢查錯誤而導致復原,這樣也會消耗到gas費 另外還有assert()、revert()、throw的寫法,不過一般用require()檢查就夠用了 --------------------------------------- function getArticles(uint256 index, uint256 count) public view returns (address[] memory, string[] memory, uint256[] memory, string[] memory) { require(count>=1); require(index+count-1<articleArray.length); address[] memory outWriterArray=new address[](count); string[] memory outWriterNameArray=new string[](count); uint256[] memory outTimeArray=new uint256[](count); string[] memory outArticleArray=new string[](count); for(uint i=0; i<count; i++){ outWriterArray[i]=writerArray[index+i]; outWriterNameArray[i]=writerNameArray[index+i]; outTimeArray[i]=timeArray[index+i]; outArticleArray[i]=articleArray[index+i]; } return (outWriterArray, outWriterNameArray, outTimeArray, outArticleArray); } 取得多篇文章的資料,從index開始取得count個文章,然後回傳4個陣列變數,注意4個陣列在一開始就必須設定好空間大小,因為memory的陣列不能使用push()一個一個動態塞入,只有storage的鏈上陣列資料才能這樣做,下面提到的函數addArticle()就是用動態的方式塞入新資料 值得一提的是,在JavaScript中有回傳多個變數時是以陣列的形式來呈現: let data = await contract.getArticles(startIndex, getCount); 接著就可以用data[0][index]、data[1][index]、data[2][index]、data[3][index]來讀取各別文章的資料 --------------------------------------- function addArticle(string memory str) public { require(bytes(str).length>0 && bytes(str).length<=3000);//utf8中文字最多1000字 writerArray.push(msg.sender); writerNameArray.push(addrNameMap[msg.sender]); timeArray.push(block.timestamp); articleArray.push(str); } 增加一篇文章的函數,utf8一個中文字一般會有3 bytes,所以限制1000字的話要給3000 bytes限制,不過這也意味著實際上可以塞到3000個英文字 值得注意的是string沒有提供length的功能,所以要先轉成bytes才能知道string的長度 block.timestamp代表現在區塊的時間 --------------------------------------- function testMassArticle(uint256 num) public { require(msg.sender==founderAddr); string memory name=addrNameMap[msg.sender]; string[4] memory strArray=["0", "1", "2", "3"]; for(uint i=0; i<num; i++){ writerArray.push(msg.sender); writerNameArray.push(name); timeArray.push(block.timestamp); articleArray.push(strArray[i%4]); } } 因為測試的時候需要產生大量的文章,所以一篇一篇產生太浪費時間也比較浪費gas,這裡寫了一個函數可以大量新增文章,使用require(msg.sender==founderAddr)來確保只有建立合約的人才能使用這個測試函數,這個就是之前提到的管理員專用的函數 --------------------------------------- function isUsedName(string memory name) public view returns (bool) { return nameUseMap[name]; } 檢查名字是否已經被使用 --------------------------------------- function getWriterName(address addr) public view returns (string memory) { return addrNameMap[addr]; } 取得帳戶位址現在設定的名字 --------------------------------------- function setWriterName(string memory name) public { require(bytes(name).length>0 && bytes(name).length<=90);//utf8中文字最多30字 require(nameUseMap[name]==false); string memory oldName=addrNameMap[msg.sender]; if(bytes(oldName).length!=0){ nameUseMap[oldName]=false; } nameUseMap[name]=true; addrNameMap[msg.sender]=name; } 設定帳戶位址的名字,除了基本的檢查之外,要注意把舊的名字設回沒有使用 solidity中要檢查空字串的話要直接看其長度是否為0 --------------------------------------- 合約的程式碼解說就到這裡,至於HTML、JavaScript的程式碼就比較沒什麼想特別說的,Web3的部份的功能都是之前有提到過的,想看程式碼的人可以到這裡看:https://github.com/vcckvv/SmartContract/blob/gh-pages/CoolChat/index.html 這次的合約程式碼雖然比之前複雜,不過基本的邏輯運作還是很簡單,下一篇要來挑戰更難的去中心化交易所,會用到比較複雜的資料結構和介面操作
這次要來介紹怎麼把代幣存到合約中,然後讓合約來處理自己的資產,順便也會提到怎麼在自己合約中呼叫別的鏈上合約的函數,沒看過之前智能合約的介紹的話可以先去看一下之前的文章: (1) https://noise.cash/post/jgmg36rhn05wx (2) https://noise.cash/post/r6v7389f5k67z (3) https://noise.cash/post/66xr32vf23r65 (4) https://noise.cash/post/n4qngmpb0n34w 代幣分成二種:原生代幣和ERC20代幣,這次二種都會用到,原生代幣就像以太坊中的以太幣,本身並沒有ERC20合約在運作,其轉移的方式是直接透過區塊鏈系統本身,而非透過合約 接下來我們直接看這次的合約程式碼: https://github.com/vcckvv/SmartContract/blob/gh-pages/DepositCoin/DepositCoin.sol -------------------------------------- pragma solidity ^0.4.0; interface Token{ function balanceOf(address owner) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function transferFrom(address from,address to,uint256 value)external returns (bool); } contract DepositCoin { address tokenAddr; function getContractBalance() public view returns (uint256) { return address(this).balance; } function pay() public payable{ } function withdraw() public{ msg.sender.transfer(1 wei); } function withdraw(uint256 v) public{ msg.sender.transfer(v); } function setTokenAddr(address addr) public{ tokenAddr=addr; } function getTokenAddr() public view returns (address) { return tokenAddr; } function getTokenBalance() public view returns (uint256) { Token t = Token(tokenAddr); return t.balanceOf(msg.sender); } function getContractTokenBalance() public view returns (uint256) { Token t = Token(tokenAddr); return t.balanceOf(this); } function depositToken(uint256 v) public{ Token t = Token(tokenAddr); t.transferFrom(msg.sender, this, v); } function withdrawToken(uint256 v) public{ Token t = Token(tokenAddr); t.transfer(msg.sender, v); } } -------------------------------------- (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) -------------------------------------- 解說: interface Token{ function balanceOf(address owner) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function transferFrom(address from,address to,uint256 value)external returns (bool); } 由於這次我們會呼叫到鏈上其他合約的函數,所以要先建立一個interface資料,之後我們會再提到要怎麼去呼叫 注意這裡不用把ERC20的所有函數都列出來,只需要列出有呼叫到的部份就好 -------------------------------------- function getContractBalance() public view returns (uint256) { return address(this).balance; } 這個函數可以讀取這個合約自身擁有多少原生代幣,this是指這個合約本身,address(this)就是這個合約發布的位址,.balance則是讀取位址的餘額 -------------------------------------- function pay() public payable{ } 這個payable函數在執行時可以另外給出指定數目的原生代幣給合約,除了接收代幣之外沒有其他功能所以無內容,不過某些合約會額外進行emit event的動作,這個之後有想做的時候再來詳細講解 (補充:呼叫者傳了多少原生代幣,可以用msg.value來讀取) 當我們在Remix上用內建虛擬機進行操作時,介面中有一個VALUE輸入框,旁邊可以指定不同單位:Wei、Gwei、Finney、Ether,在VALUE輸入框輸入想要傳送的原生代幣數值後,此時按下紅色的pay函數按鈕就可以傳送原生代幣給合約 另外一提,在JavaScript上執行payable函數是這樣: const options = {value: ethers.utils.parseEther("0.00000001")};//指定傳送0.00000001 Ether給合約 let tx = await contractWithSigner.pay(options); pay函數本身沒有參數,所以是加一個options的參數,如果pay函數本身有多個參數,則options的參數會加到所有參數的最後面去,比如: let tx = await contractWithSigner.pay(param1, param2, options); 完整的測試運作程式碼在https://github.com/vcckvv/SmartContract/blob/gh-pages/DepositCoin/index.html 可以到https://vcckvv.github.io/SmartContract/DepositCoin/ 上面進行測試運作,按下那個pay按鈕就會執行上面說的pay()函數 要查詢結果或進行其他的功能可以到https://goerli.etherscan.io/address/0x416d91a77948ca36f79a9609c239a41bd5e0e566#readContract 的合約互動介面上去做,因為沒其他新東西所以這次不另外講解網頁程式碼 另外一樣要注意一下如果有多個人同時進行測試,有可能會產生意外的結果,這個時候就要注意這個合約的交易狀況: https://goerli.etherscan.io/address/0x416d91a77948ca36f79a9609c239a41bd5e0e566 -------------------------------------- function withdraw() public{ msg.sender.transfer(1 wei); } function withdraw(uint256 v) public{ msg.sender.transfer(v); } 這裡寫了二種出金函數,一種是執行後會固定傳送原生代幣1 wei給使用者,另一種則是可以指定傳送的數量有多少wei,因為輸入參數不同,所以用同樣的函數名也可以 msg.sender.transfer(v)這個程式碼的實際作用是把合約的原生代幣傳給msg.sender 另外除了wei這個單位外,還有gwei(10^9 wei)、ether(10^18 wei)的單位可以用 -------------------------------------- 補充一下,solidity目前沒內建支援浮點數,所以原生代幣和ERC20代幣的數值都是採用「uint256儲存和處理數值」+「固定位數的小數點顯示」的方式來呈現,原生代幣1 wei就是最低單位 -------------------------------------- function setTokenAddr(address addr) public{ tokenAddr=addr; } 這個函數是用來設定ERC20代幣合約的位址,設定完之後我們才可以使用其他的函數來轉移這種ERC20代幣,而我們測試的當然是之前創造的TestToken,合約位址為:0x63E1ddeB828eD1634B3165f56e2F31950b4d0B93 沒拿過的人可以到https://vcckvv.github.io/SmartContract/TestToken/ 的水龍頭網站領取 -------------------------------------- function getTokenBalance() public view returns (uint256) { Token t = Token(tokenAddr); return t.balanceOf(msg.sender); } function getContractTokenBalance() public view returns (uint256) { Token t = Token(tokenAddr); return t.balanceOf(this); } 這二個函數是用來讀取使用者帳戶或這個合約中擁有的ERC20代幣數量,使用我們之前設定好的interface Token以及代幣合約的位址,就能呼叫代幣合約的balanceOf函數 -------------------------------------- function depositToken(uint256 v) public{ Token t = Token(tokenAddr); t.transferFrom(msg.sender, this, v); } 這個函數是把使用者帳戶的ERC20代幣存到這個合約中,但要注意的是,由於動用到的是transferFrom函數(function transferFrom(address from, address to, uint256 value),把value的代幣值從from帳號轉移到to帳號),因為ERC20代幣的安全規範限制,需要使用者先到代幣合約那邊執行approve函數 approve函數的輸入參數是「一個位址和一個數值」(function approve(address spender, uint256 value)),代表帳戶允許那個位址的人最多動用到多少自己手上的代幣,假設已經設成100,則這裡的transferFrom函數最多就只能移動100個代幣 所以要測試的話,就先要執行以下網頁的互動介面的approve函數,spender位址參數就填入這個合約的位址:0x416d91a77948ca36f79a9609c239a41bd5e0e566 https://goerli.etherscan.io/address/0x63E1ddeB828eD1634B3165f56e2F31950b4d0B93#writeContract 因為ERC20代幣的安全規範,同時又因為solidity的呼叫其他合約函數的限制,我們無法在自己的合約中呼叫approve而讓使用者帳戶直接允許合約動用它的代幣,所以目前只能要求使用者依序呼叫二種函數才能完成存入代幣的動作,一般的做法是讓approve一次把允許的數量拉到最大,這樣之後就不用每次都再呼叫approve -------------------------------------- function withdrawToken(uint256 v) public{ Token t = Token(tokenAddr); t.transfer(msg.sender, v); } 這個函數是把這個合約擁有的ERC20代幣出金到使用者帳戶中,做法和depositToken差不多,只是換成呼叫transfer函數(function transfer(address to, uint256 value),把value的代幣值從呼叫者帳號轉移到to帳號),transfer函數是由這個合約呼叫,所以是把合約擁有的幣轉移給現在的msg.sender -------------------------------------- 最後來提一下智能合約的位址產生方式,智能合約的位址是用「創造者的帳號位址」+「nonce」(每次交易都會增加的數字)丟給keccak256的hash函數來產生,所以本身沒有密鑰,如果把代幣直接傳到合約位址的話,就只能仰賴合約自身的出金函數來想辦法取出 所以為了避免有人亂傳,有些智能合約會設置一個出金函數,用來處理代幣亂傳的情況,不過當然會設定成只有管理員帳戶才能存取,怎麼設定管理員帳戶之後會提到 把代幣存到合約中的功能就介紹到這裡,下一篇我們要利用區塊鏈功能來打造一個Web3線上聊天室,裡面全部的文章都會上鏈,敬請期待~
依照預告,這次要實作ERC20代幣的水龍頭網站,沒看過之前智能合約的介紹的話可以先去看一下之前的文章: (1) https://noise.cash/post/jgmg36rhn05wx (2) https://noise.cash/post/r6v7389f5k67z (3) https://noise.cash/post/66xr32vf23r65 首先實際操作一遍水龍頭網站看看: https://vcckvv.github.io/SmartContract/TestToken/ 和之前一樣,要安裝MetaMask的瀏覽器外掛才能運作,沒有goerli的代幣可以到那個goerli水龍頭網站連結領取:https://goerlifaucet.com/ 這次有加入切換成goerli鏈的功能,所以不用再先自行切換,MetaMask會自動跳出一個視窗要你切換到goerli鏈 連結帳戶、切換goerli鏈完成後,接下來就按下「新增TestToken代幣資料到MetaMask」的按鈕,MetaMask會自動跳出一個視窗要你新增一種新的ERC20代幣TestToken(如圖一),按下那個Add Token按鈕就可以看到Assets多了新的代幣TEST 接下來按下「獲得TestToken代幣」的按鈕,就會跳出一個視窗要求簽署交易,簽署完等待交易上鏈,就可以看到帳戶中代幣TEST多了8.00元(如圖二) 接下來讓我們來看一下網頁的完整程式碼: https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/index.html --------------------------------------- <html> <head> <title>TestToken水龍頭</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <input id="showAddress" readonly size="50" /><input id="showBalance" readonly /><br> <button onclick="onAddTokenBtn()">新增TestToken代幣資料到MetaMask</button><br> <button onclick="onGetTokenBtn()">獲得TestToken代幣</button><br> <a href="https://goerlifaucet.com/" target="_blank">goerli水龍頭網站</a> </body> <script src="https://cdn.ethers.io/lib/ethers-5.1.umd.min.js"></script> <script> // The Contract interface const abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]; const contractAddress = "0x63E1ddeB828eD1634B3165f56e2F31950b4d0B93"; let address = null; let provider = null; let contract = null; let contractWithSigner = null; async function init(){ try{ let response = await window.ethereum.request({method: 'eth_requestAccounts'}); address = response[0]; document.querySelector('#showAddress').value=address; //切換到goerli測試鏈 await window.ethereum.request({method: 'wallet_switchEthereumChain', params: [{ chainId: '0x5' }],}); provider = new ethers.providers.Web3Provider(window.ethereum); let balanceNum=await provider.getBalance(address); document.querySelector('#showBalance').value=ethers.utils.formatEther(balanceNum); contract = new ethers.Contract(contractAddress, abi, provider); contractWithSigner = contract.connect(provider.getSigner() ); }catch(err){ alert(err.message); } } init(); window.ethereum.on('accountsChanged', function (accounts) { init(); }); window.ethereum.on('chainChanged', async function(networkId){ if(networkId!=5){ alert("this only works on goerli"); await window.ethereum.request({method: 'wallet_switchEthereumChain', params: [{ chainId: '0x5' }],}); } }); async function onAddTokenBtn(){ try { const isAdded = await window.ethereum.request({ method: 'wallet_watchAsset', params: { type: 'ERC20', options: { address: contractAddress, symbol: "TEST", decimals: 2, image: "https://vcckvv.github.io/SmartContract/TestToken/icon.png", }, }, }); }catch(error){ alert(err.message); } } async function onGetTokenBtn(){ try{ let tx = await contractWithSigner.mint(); alert("https://goerli.etherscan.io/tx/" + tx.hash); }catch(err){ if(err.code==4001){//reject alert("User rejected tx."); } else{ alert(err.message); } } } </script> </html> --------------------------------------- 噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製 另外因為噪音會自動把網址前面的https://去掉,所以我把程式碼中的網址的冒號: 都換成全形的冒號: --------------------------------------- let response = await window.ethereum.request({method: 'eth_requestAccounts'}); address = response[0]; document.querySelector('#showAddress').value=address; 上次沒特別提到,進行MetaMask帳戶連結後得到的response[0]就是這個帳戶的位址,這次用一個輸入框顯示出來 --------------------------------------- await window.ethereum.request({method: 'wallet_switchEthereumChain', params: [{ chainId: '0x5' }],}); 這次新增了切換到goerli測試鏈的功能,那個0x5就是goerli鏈的ID,如果是smartBCH鏈的話就要換成0x2710 --------------------------------------- let balanceNum=await provider.getBalance(address); document.querySelector('#showBalance').value=ethers.utils.formatEther(balanceNum); 這次也額外做了顯示帳戶擁有的原生代幣餘額,要注意provider.getBalance()取得的是沒有小數點的大數,所以還要使用ethers.utils.formatEther()轉換成有小數點的字串 --------------------------------------- window.ethereum.on('accountsChanged', function (accounts) { init(); }); 這個程式碼用來設定在使用者轉換帳號時要執行的函數,這裡只需要重新呼叫init()就好了 --------------------------------------- window.ethereum.on('chainChanged', async function(networkId){ if(networkId!=5){ alert("this only works on goerli"); await window.ethereum.request({method: 'wallet_switchEthereumChain', params: [{ chainId: '0x5' }],}); } }); 這個程式碼用來設定在使用者轉換區塊鏈時要執行的函數,如果不是goerli鏈就會要求切換回去 --------------------------------------- const isAdded = await window.ethereum.request({ method: 'wallet_watchAsset', params: { type: 'ERC20', options: { address: contractAddress, symbol: "TEST", decimals: 2, image: "https://vcckvv.github.io/SmartContract/TestToken/icon.png", }, }, }); 這一段程式碼就是在帳戶中新增ERC20代幣的資料,其中image參數是這個代幣的圖片網址,弄成像素值40X40的圖片大小就好 值得一提的是,MetaMask目前沒有提供函數來判斷帳戶Assets中有哪些ERC20代幣,而且即便已經新增過代幣,執行新增代幣的程式碼還是會跳出一個視窗,所以只能設成用按按鈕的形式來新增代幣 --------------------------------------- let tx = await contractWithSigner.mint(); 這次獲取代幣的方式就只是執行鑄造函數mint(),雖然也可以弄成把合約中的儲備代幣轉移過來,不過那涉及到怎麼把代幣轉移給合約的問題,那個我們預定下一篇再說,這一篇就先解說到這裡

今天卜問的是去中心化交易所的dYdX(DYDX幣) 卜問dYdX一年之內的發展如何?卜得履初九訟 履初九,素履,往,无咎。 [變卦訟]初六,不永所事,小有言,終吉。 看資料dYdX也算在以太坊的Layer2方案之中,專攻於的合約期貨以及槓桿交易,也就是衍生性金融商品(Derivative)(Derivative也是數學的導數,所以才命名成這樣),最早的期貨交易會被發明出來是為了轉移風險,讓農作物的收購價格可以保持穩定,而「轉移風險」正好符合本卦履卦的謹慎避開危險的性質 最近有關dYdX的大新聞應該是其預計要退出以太坊、自建公鏈,會離開當然是因為以太坊目前的總總缺點,依照之前以太坊的占卜結果來看( https://noise.cash/post/4xj7xjgawp4rg ),發展結果並不好,dYdX能提早退出正好避開了一些麻煩紛爭,所以變卦爻辭說「不永所事,小有言,終吉」 不過因為本卦的爻辭「素履,往,无咎」,說明dYdX這一年不會有什麼顯眼的發展,自建公鏈的開發時間有可能不會太快,或是建好後不會很快就有很大的聲勢人氣,需要多點的時間才能有較好的市場表現 2022年7月25日1時
今天卜問的是DeFi的BarnBridge(BOND幣) 卜問BarnBridge一年之內的發展如何?卜得漸上九蹇 漸上九,鴻漸于陸,其羽可用為儀,吉。 [變卦蹇]上六,往蹇來碩,吉,利見大人。 BarnBridge的主要目標是要透過代幣化來進行風險轉移,或說是「收益率分層」,比如說有一個項目的年利率波動很大,而A有700萬、B有300萬合資投入,在一般情況下那利息就是7:3分成,不過BarnBridge允許A可以保持穩定領5%利息,多的利息都給B,這時如果波動年利率夠高,會讓B比單投300萬要來得賺更多;但反過來說如果波動的年利率太低,則B要出錢來補給A,確保A一定可以領到5%利息 也就是說這個系統把A的風險轉移了給B,B則是有機會賺更多,但也可能賠錢,而這裡的漸卦代表變動、蹇卦代表穩定的錢滾錢,因此符合BarnBridge的性質 從卦象來看,這個卦並不適合向外發展、擴張,而是適合保持穩穩賺的方式前進,如果BarnBridge開發團隊沒有做多餘的計畫的話,那麼應該有機會在熊市中也能穩穩發展,我認為算是有潛力的一個項目 不過看了一下BOND最近的走勢直接向上噴出,漲了快7倍左右,這種炒作方式不太適合BarnBridge的本質,要注意爻辭「鴻漸于陸」,大雁飛一飛還是要回到陸地,所以這種漲勢有可能維持不了多久 2022年7月24日0時
今天卜問的是區塊鏈遊戲平台PlayDapp(PLA幣) 卜問PlayDapp一年之內的發展如何?卜得革上六同人 革上六,君子豹變,小人革面,征凶,居貞吉。 [變卦同人]上九,同人于郊,无悔。 PlayDapp的主要目標是要建立一個平台,讓用戶可以在不同的遊戲中買賣NFT資產,主要交易的方式是C2C(Consumer-to-consumer),也就是用戶和用戶之間的私自交易,這點就符合變卦同人卦「與人相會合」的性質 看新聞PlayDapp今年三月有和三星物產度假部簽署合作,不過主要內容是要在主題公園中建立元宇宙的服務,這點符合變卦爻辭「同人于郊」,不過本質上和PlayDapp應該要專注的本業並不相同,所以雖然能從中獲利但本身不會有太大的發展,如爻辭「征凶,居貞吉」所示 會這樣改變發展方向我猜是原本的本業就發展不好,所以改變了發展方向來求生存,而革上爻就是一個改變完成的一卦,此時就不應再繼續改變,保持這條路繼續走下去就好,以今年熊市的狀態來說有找到可以求生存的獲利方式就算是好事了 2022年7月23日0時 ------------------------------------------- 回顧一下Polygon的占卜結果:https://noise.cash/post/9z9np5gc0z5m6 最近看到這二則新聞: Polygon 宣布推出 L2 方案虛擬機 zkEVM ,Matic 單日暴漲 29.44% https://www.blocktempo.com/polygon-to-launch-zkevm-on-july-21/ 在迪士尼為其 2022 年加速器計劃選擇 Polygon 之後,MATIC 看到了巨大的看漲推動力 https://zh-tw.bitcoinethereumnews.com/technology/matic-sees-huge-bullish-boost-after-disney-selected-polygon-for-its-2022-accelerator-program-%E2%8B%86-zycrypto/ 如預測一樣,Polygon開發出獨立於ETH之外的功能zkEVM,也在市場中變得穩固下來,不過因為占卜的旅卦是追求小利的一卦,所以我認為這些聲勢都只是短期的,後續還要小心一些意外發生
依照預告,這次要來實作ERC20代幣,沒看過之前智能合約的介紹的話可以先去看一下之前的文章: (1) https://noise.cash/post/jgmg36rhn05wx (2) https://noise.cash/post/r6v7389f5k67z 在解釋實作程式碼之前先來介紹什麼是ERC20,所謂的ERC20就是一種智能合約的標準協議,只要合約內的函數介面滿足其規定所需要的條件,那麼就可以被視為一種有代幣功能的智能合約,而具體的條件就是需要含有totalSupply、balanceOf、allowance、transfer、approve、transferFrom這些函數,除此之外一般還需要設定合約的狀態變數name、symbol、decimals 在實作上我們可以直接複製其他人寫好的範例,不用自己重新寫出全部內容,這裡使用的範例來源是: https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v2.0.0/contracts/token/ERC20 首先複製這三個檔案到我們的Remix編譯器上,全都放到同一個資料夾之下就好: ERC20.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/ERC20.sol IERC20.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/IERC20.sol SafeMath.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/SafeMath.sol 之後創造我們的代幣合約TestToken.sol: https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/TestToken.sol ----------------------------------- pragma solidity ^0.4.19; import "./ERC20.sol"; contract TestToken is ERC20 { string public name = "TestToken"; string public symbol = "TEST"; uint8 public decimals = 2; uint256 public INITIAL_SUPPLY = 88888; constructor() public { _mint(msg.sender, INITIAL_SUPPLY); } function mint() public { _mint(msg.sender, 800); } } ------------------------------------ (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) -------------------------------- import "./ERC20.sol"; 這一行用來引用其他的sol程式碼檔案,因為會使用到ERC20這個contract ------------------------------------ contract TestToken is ERC20 { 這一行就像是C++中的繼承功能,也就是說TestToken會繼承ERC20的變數和函數,這樣做的話大部份的函數都不用重寫 ------------------------------------ string public name = "TestToken"; string public symbol = "TEST"; uint8 public decimals = 2; uint256 public INITIAL_SUPPLY = 88888; name就是代幣的完整名字,而symbol就代幣的縮寫代碼,INITIAL_SUPPLY代表一開始鑄造的代幣數量 decimals則是指代幣數量的小數點位置,比如這裡設定為2,擁有數量88888則實際上會顯示888.88;如果設定為3,擁有數量88888則實際上會顯示88.888 在變數後面加上public修飾詞,代表會自動生成相應的合約的讀取函數:name()、symbol()、decimals()、INITIAL_SUPPLY(),這樣的話我們就不用再另外寫變數的讀取函數 ------------------------------------ constructor() public { _mint(msg.sender, INITIAL_SUPPLY); } constructor()只在創造合約時呼叫,而msg.sender代表呼叫這個函數的帳戶位址,所以此時的msg.sender就是創造者的帳戶位址 _mint會進行代幣的鑄造,會把一開始的代幣全部移到msg.sender的帳戶之中 ------------------------------------ function mint() public { _mint(msg.sender, 800); } 這個函數是用來製作水龍頭功能的鑄造代幣函數,每次鑄造固定給予8.00個代幣 由於_mint()是無法公開呼叫的internal函數,TestToken繼承這種函數後無法讓它公開呼叫,所以我們要再弄一個public函數來進行鑄造,此時的msg.sender就是呼叫這個函數的使用者帳戶位址 ------------------------------------ 接著把這個合約發布到goerli測試鏈上:https://goerli.etherscan.io/address/0x63e1ddeb828ed1634b3165f56e2f31950b4d0b93#code 然後在MetaMask的goerli測試鏈的Assets頁面的下面中點選Import tokens連結,Token Contract Address輸入合約位址0x63e1ddeb828ed1634b3165f56e2f31950b4d0b93,接著Token Symbol和Token Decimal應該會自動填上,之後按Add Custom Token按鈕,再按下Import Tokens按鈕就可以看到一開始鑄造的888.88 TEST代幣了,如圖一 鑄造自己的ERC20代幣就講解到這裡,下一篇來講解怎麼利用這個代幣合約來寫一個水龍頭網站
續前篇:https://noise.cash/post/jgmg36rhn05wx 這次要來寫一個網頁程式來和前一篇發布的合約進行互動,這裡假設看的人已經對HTML和JavaScript有一定的了解,所以只會談論連結MetaMask帳戶、和合約互動的程式碼的部份 首先先實際操作一下完成的網頁:https://vcckvv.github.io/SmartContract/HelloWorld/ 沒有MetaMask錢包的人要先安裝MetaMask錢包瀏覽器外掛,因為這個網頁是預設和MetaMask進行連結 第一次連進去應該會要求帳戶的連線,由於這個程式沒有寫切換到goerli測試鏈的功能,所以記得要手動切換到goerli測試鏈上,另外如果沒goerli的幣的話,可以先去水龍頭網站領取:https://goerlifaucet.com/ 按下getValue的按鈕會執行合約中的get()函數,也就是取得合約中value的資料,然後顯示在左邊的輸入框上 按下setValue的按鈕則會執行合約中的set()函數,會把左邊的輸入框中的文字當作輸入參數來執行,按下後會跳出MetaMask的交易確認,接著網頁會等到交易上鏈後再自動執行get()函數,由此顯示出我們的set()函數操作有正確改變合約中value的資料 值得注意的是,如果有多個人在同時間測試的話,value會被設定成最後一個人修改的資料,這個時候就要注意一下合約的交易情況: https://goerli.etherscan.io/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5 接下來看一下完整網頁程式: https://github.com/vcckvv/SmartContract/blob/gh-pages/HelloWorld/index.html ---------------------------------------------------- <html> <head> <title>Hello World</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <input id="showValue" readonly></input><button onclick="onGetValueBtn()">getValue</button><br> <input id="newValue" ></input><button onclick="onSetValueBtn()">setValue</button> </body> <script src="https://cdn.ethers.io/lib/ethers-5.1.umd.min.js"></script> <script> // The Contract interface const abi = [{"constant": false,"inputs": [{"name": "v","type": "string"}],"name": "set","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": true,"inputs": [],"name": "get","outputs": [{"name": "","type": "string"}],"payable": false,"stateMutability": "view","type": "function"},{"inputs": [],"payable": false,"stateMutability": "nonpayable","type": "constructor"}]; const contractAddress = "0x8abb77ff22f8966729603bd49c5c049c4294efd5"; let address = null; let provider = null; let contract = null; let contractWithSigner = null; async function init(){ try{ let response = await window.ethereum.request({method: 'eth_requestAccounts'}); address = response[0]; provider = new ethers.providers.Web3Provider(window.ethereum); contract = new ethers.Contract(contractAddress, abi, provider); contractWithSigner = contract.connect(provider.getSigner() ); }catch(err){ alert(err.message); } } init(); async function onGetValueBtn(){ try{ let currentValue = await contract.get(); document.querySelector('#showValue').value=currentValue; }catch(err){ alert(err.message); } } async function onSetValueBtn(){ try{ let newValue=document.querySelector('#newValue').value; let tx = await contractWithSigner.set(newValue); alert(tx.hash); document.querySelector('#showValue').value=""; await tx.wait(); onGetValueBtn(); }catch(err){ if(err.code==4001){//reject alert("User rejected tx."); } else{ alert(err.message); } } } </script> </html> ---------------------------------------------------- (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) ---------------------------------------------------- 由於MetaMask沒辦法在打開本機上的HTML檔時開啟功能,所以在測試的時候要放到伺服器上來進行測試,我一般都是在自己電腦上建立一台網頁伺服器,然後放在上面進行測試比較方便,使用的軟體是Http File Server:https://www.rejetto.com/hfs/ ---------------------------------------------------- 這次使用的函數庫是ethers.js,個人的使用經驗上感覺非常便利,這裡只需要簡單地引用這個js檔就能使用: <script src="https://cdn.ethers.io/lib/ethers-5.1.umd.min.js"></script> 注意因為噪音會自動把網址前面的https://去掉,所以我把程式碼中的網址的冒號: 都換成全形的冒號: ---------------------------------------------------- const abi = [{"constant": false,"inputs": [{"name": "v","type": "string"}],"name": "set","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": true,"inputs": [],"name": "get","outputs": [{"name": "","type": "string"}],"payable": false,"stateMutability": "view","type": "function"},{"inputs": [],"payable": false,"stateMutability": "nonpayable","type": "constructor"}]; 這串abi代表合約的函數介面資料,之前在Remix進行編譯時(Compile HelloWorld.sol),編譯完介面底下會出現一個ABI的按鈕,按下去就會把產生的ABI資料複製起來,然後就可以貼到程式碼這邊 要注意之後在處理多個contract的情況時,要在上面的CONTRACT下拉表中選對發布的contract,才能得到正確的ABI ---------------------------------------------------- let response = await window.ethereum.request({method: 'eth_requestAccounts'}); address = response[0]; provider = new ethers.providers.Web3Provider(window.ethereum); contract = new ethers.Contract(contractAddress, abi, provider); contractWithSigner = contract.connect(provider.getSigner() ); 這一段就是進行MetaMask的帳戶連結,然後產生provider物件,provider物件基本功能應該是和RPC Server相連線,由此和合約進行互動 RPC Server的網址就是MetaMask設定的區塊鏈的資料中的RPC URL,如果不是商業用的RPC Server也許會有些流量限制,不過測試的時候應該不用考慮那麼多,直接用預設的免費RPC Server就好 產生provider物件之後再產生contract和contractWithSigner物件,這兩個後面和合約互動時會用到 ---------------------------------------------------- let currentValue = await contract.get(); document.querySelector('#showValue').value=currentValue; 要執行合約中讀取性質的函數的方法很簡單,像是我們要執行合約中的get(),就只需要寫成contract.get()就可以了,要注意這個動作會動用到網路,所以是非同步函數,因此要用await去等待值回傳回來 而在JavaScript使用到await的話,函數就要加上async,代表這個函數裡面有非同步的指令,而我們這裡的函數都有用到,所以都有加上async ---------------------------------------------------- let newValue=document.querySelector('#newValue').value; let tx = await contractWithSigner.set(newValue); alert(tx.hash); document.querySelector('#showValue').value=""; await tx.wait(); onGetValueBtn(); 而要執行合約中寫入性質的函數的方法也很簡單,像是我們要執行合約中的set(),就只需要寫成contractWithSigner.set()然後再填入輸入的參數就可以了 執行這個函數後回傳的是交易資料tx,我們可以用await tx.wait()來等待交易上鏈完成,然後繼續其他的動作,這裡是執行onGetValueBtn()用來確定我們的值有真的在鏈上被修改掉 值得一提的是,如果在MetaMask中把pending的交易啟用加速功能(需要多給費用),那麼即使交易上鏈完成,這裡的tx.wait()也沒辦法回傳繼續行動,這個也不能說算是MetaMask的bug,因為本質上算是換成不同的交易 ---------------------------------------------------- 和合約互動的基本功能這樣就完成了,不過還是有些東西沒有提到,像是切換區塊鏈、偵測帳號切換、取得帳號餘額,這些之後會再加進來講解,這裡只寫一些最基本的功能 下一篇要來解說怎麼製作自己的ERC20代幣,之後還會弄個水龍頭網站,敬請期待~
雖然之前也改過某山寨幣的錢包兼挖礦程式,不過感覺這年頭沒寫個智能合約都沒臉跟人說自己在幣圈中也是懂點技術的人,所以接下來打算寫幾篇簡單的智能合約介紹,以及講解能和智能合約互動的Web3網頁 按照慣例,第一篇就來寫個HelloWorld程式,智能合約的HelloWorld程式就是設置一個合約的狀態變數value,然後設一個函數get()用來讀取,再設一個函數set()用來寫入,這裡的解說會假設閱讀者已經對程式語言有基本的了解,會寫簡單的程式只是沒碰過智能合約程式,所以不會從程式的基本開始講解 以下為完整程式碼: https://github.com/vcckvv/SmartContract/blob/gh-pages/HelloWorld/HelloWorld.sol -------------------------------- pragma solidity ^0.4.0; contract HelloWorld { string value; constructor() public { value = "HelloWorld!"; } function get() public view returns (string memory) { return value; } function set(string memory v) public { value = v; } } -------------------------------- (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) -------------------------------- pragma solidity ^0.4.0;這一行是用來指示編譯器的最低版本,設定後可以用的版本是0.4.X,另外更新的版本會有些新功能可以使用,不過有些地方的寫法也會不太一樣,這裡作為練習就先使用這個版本,之後才打算換成新版本來寫 -------------------------------- contract HelloWorld { 這一行用來設定合約的名字HelloWorld,被大括號{}圍住的部份就是合約的內容 -------------------------------- string value; 放在合約內宣告的變數即為合約的狀態變數,代表這筆字串資料value會存在區塊鏈上 -------------------------------- constructor() public { value = "HelloWorld!"; } constructor()函數只會在合約發布時執行一次,之後就不能再呼叫,主要用來對一些變數進行初始化設定,這裡就把value設定成"HelloWorld!"這個字串 -------------------------------- function get() public view returns (string memory) { return value; } 讀取的函數get()用view returns修飾詞後面再接上想回傳的變數型態 這裡的string如果是區域變數則要加上memory的修飾詞,代表執行完後就會消失的暫時變數資料,反過來如果是會留在鏈上的變數資料則是加storage的修飾詞,不過使用上比較像是指標,之後有用到的話再去詳細解釋 函數後面加上public修飾詞,代表這些函數可以被自由地公開呼叫,後面有機會的話還會再提到其他的修飾詞,有些只能被內部使用、無法公開呼叫 -------------------------------- function set(string memory v) public { value = v; } 寫入的函數就只需要加上public修飾詞就好,也不用進行回傳 -------------------------------- 這裡使用的編譯器是Remix:https://remix.ethereum.org/ ,因為是線上網頁編譯器,所以打開就可以用,個人用起來的經驗是覺得還算方便,就算網頁當掉也有自動存檔,缺點大概就是虛擬機跑得很慢、容易當掉 介面打開後如圖一,點選左邊的File explorers按鈕後會出現檔案列表,一開始會有些範例檔案,因為不重要所以可以全刪掉,接著點選裡面Create New File的按鈕來新增檔案HelloWorld.sol,接著會自動開啟新的編輯視窗,之後就可以把上面的合約的程式碼複製進去,按Ctrl+S可以存檔加自動編譯 然後按左邊的Solidity Compiler按鈕,就會出現編譯器介面,因為會自動判斷程式碼指示的編譯器版本,所以應該會自動轉成0.4.26的編譯器版本,如果沒有就自己點選版本,確定沒問題就按下Compile HelloWorld.sol的按鈕,成功的話就不會出現錯誤,且Solidity Compiler按鈕上會出現一個勾號 接著進到發布智能合約的環節,按下左邊的Deploy & run transactions按鈕,一開始測試的時候先在內建的虛擬機上運行會比較方便,所以ENVIRONMENT是選Remix VM,ACCOUNT代表要發布合約的帳號,直接用預設的就好,CONTRACT應該是顯示HelloWorld - HelloWorld.sol這個合約,如果之後要寫內含多個contract的程式碼,要注意一下這個地方不要選錯主要發布的合約,免得之後實際發布的時候浪費錢 全部確定之後就按下Deploy按鈕,接著下面會產生一個操作函數介面,一開始是縮起來的,點選>箭頭按鈕打開後會呈現圖二的樣子 按下get按鈕後會執行get()函數,然後顯示出回傳的值:「0: string: HelloWorld!」 在set按鈕旁邊可以輸入字串,這裡填入test然後按下set按鈕,這樣的話就會把test當作輸入字串執行set()函數 為了要檢查結果,我們再按下get按鈕,然後顯示出回傳的值:「0: string: test」,這樣就代表value的值在虛擬機中有確實地被改變成設定的值 -------------------------------- 當然,如果只有在虛擬機上玩玩實在沒什麼意思,接下來我們開始發布到測試鏈上,然後在EtherScan的介面上也來實際操作看看 首先開啟MetaMask,然後換到Goerli的測試鏈上,如果沒找到的話代表被隱藏起來,此時把Show test networks選項打開就能看到,如果沒Goerli的幣的話,可以先去水龍頭網站領取:https://goerlifaucet.com/ (這個要用google帳號登入alchemy才能領,有要填資料的話隨便填填就好)、https://faucets.chain.link/goerli (很方便領取的水龍頭,不過有時會沒辦法領,剛才點進去看又變404了,可能要有緣才能領到) 這次發布時ENVIRONMENT選擇Injected Provider - MetaMask,按下Deploy按鈕後MetaMask會跳出視窗要求簽署交易,按下Confirm之後,底下結果視窗會顯示出一個view on etherscan的連結,點進去就會看見自己剛發布在測試鏈上的創立合約的交易資料: https://goerli.etherscan.io/tx/0x43ea64aec24415cac0d0d4f15c90de68001d355a2855792913d174a203c18022 如果馬上點進去看,可能這筆交易會顯示還沒上鏈,那樣的話要再等一段時間 之後頁面中有一個[Contract 0x8abb77ff22f8966729603bd49c5c049c4294efd5 Created],0x8abb77ff22f8966729603bd49c5c049c4294efd5就是這次合約的位址,接著再點進其中的連結:https://goerli.etherscan.io/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5 連結頁面底下有個Contract按鈕,按了會顯示合約編譯後的十六進位資料,不過裡面還有個Verify and Publish連結,可以把我們的程式碼輸入進去,EtherScan會自動產生操作函數的介面 點進Verify and Publish連結後,Contract Address會自動填好,Compiler Type因為是單一檔案所以選Solidity(Single file),Compiler Version選和編譯時相同的0.4.26,Open Source License Type隨便選個喜歡的就好,之後按下Continue按鈕 下一個頁面在Enter the Solidity Contract Code below底下的輸入框中複製程式碼進去,接著驗證不是機器人後就可以點下Verify and Publish按鈕,成功的話就會顯示Successfully generated ByteCode and ABI for Contract Address 之後回到https://goerli.etherscan.io/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5#code 頁面就可以看到輸入的程式碼和互動介面了 點選Read Contract按鈕開啟讀取合約互動頁面,會顯示一個項目get,按下去就會顯示現在的value資料是什麼,第一次會顯示:HelloWorld! string,如果想要更新就按旁邊的[Reset]連結 接著點選Write Contract按鈕開啟寫入合約互動頁面,首先點那個Connect to Web3,選擇MetaMask錢包進行連結,會變成Connected - Web3 [...],之後就可以開始操作下面的set函數,打開項目set後在v (string)的輸入框中輸入test,然後點下Write按鈕,MetaMask會跳出交易要你簽署,按下Confirm後就完成寫入的操作,之後就會如圖三那樣,多一個View your transaction按鈕可以看這次寫入的交易 接著等到交易成功上鏈的訊息出現後就可以再到Read Contract頁面那裡,可以看到資料變成test string -------------------------------- 另外一提,在Remix中也可以在Deploy介面中的At Address旁邊的輸入框輸入我們發布好的鏈上合約位址0x8abb77ff22f8966729603bd49c5c049c4294efd5,然後點選At Address按鈕後下面也會出現合約互動介面,這個介面可以用來和鏈上合約互動,這樣就不用每次測試時都要到etherscan那邊做Verify and Publish才能有合約互動介面 -------------------------------- 以上操作完就代表我們的合約運作沒有問題,不過我們的HelloWorld還沒結束,下一篇要來介紹一下如何寫一篇網頁來和這個合約進行互動


今天卜問的是區塊鏈DigiByte(DGB幣) 卜問DigiByte一年之內的發展如何?卜得小過初六豐 小過初六,飛鳥以凶。 [變卦豐]初九,遇其配主,雖旬无咎,往有尚。 看資料DigiByte算是早期的老幣,創辦人Jared Tate也曾參與過比特幣的開發,之後以比特幣的架構為基礎開發DigiByte,其主要的特性在於使用五種不同的演算法來挖礦:SHA256、Scrypt、Skein、Qubit 、 Odocrypt,目標是用來改善比特幣的安全性,不過以目前比特幣只用一種演算法挖礦但還是沒什麼問題的狀況來看,這種特性並沒有太大的優勢,只是讓礦機多運作一些東西,而這種「豐厚又有些多餘的試煉」就符合變卦豐卦的性質 從卦象來看,DigiByte這一年不宜有太大的計畫,本卦小過卦是宜下不宜上的一卦,越是想要做大事就越危險,另一邊變卦爻辭「遇其配主,雖旬无咎,往有尚」則說明可能會遇到合作的伙伴或金主,但是這個「配主」往往後續會帶來一些麻煩的試煉,雖說如果努力做好的話還是能獲得一些利益 從市場表現來看的話,爻辭「飛鳥以凶」可能暗示會向上發展,但是如果過高的話就容易遇到危險的意外,作為投資項目來看的話應該風險算比較高 2022年7月18日21時
今天卜問的是區塊鏈Casper(CSPR幣) 卜問Casper一年之內的發展如何?卜得遯九三否 遯九三,係遯,有疾,厲,畜臣妾吉。 [變卦否]六三,包羞。 Casper是使用 Casper CBC 規範所創建的PoS鏈,看資料最初以太坊創始人Vitalik本來是支持在以太坊上使用Casper協議來解決效能問題,不過後來因為Vitalik妥協,所以Casper團隊出走並建立了Casper這條新鏈,就其本質來說應該還是很接近ETH,只是不受ETH的種種PoW包袱限制來發展,而這種性質就符合本卦遯卦的「逃脫束縛」卦象 從卦象來說,因為本質是逃脫,所以不是面對困難、做出大事的一卦,能得到的是小利而非大利,而從爻辭「係遯,有疾,厲」來看,開發團隊仍然是為了追求利益而非為了追求理想而開發,因此比較難以期待有什麼困難技術的突破,這一年可能就專注在擴大其周邊的生態系的應用、以及各種商業合作,如爻辭「畜臣妾吉」所示 如果從市場表現來看,變卦否卦是需要漫長時間才會顯露出來的一卦,所以也許沒那麼多的大新聞,但要注意爻辭有云:「包羞」,也許暗中會做出一些不太光彩的事 2022年7月17日21時
今天卜問的是區塊鏈Secret(SCRT幣) 卜問Secret一年之內的發展如何?卜得臨上六損 臨上六,敦臨,吉,无咎。 [變卦損]上九,弗損,益之,无咎,貞吉,利有攸往,得臣无家。 Secret的前身是以太坊的L2之一的Enigma,之後因為以太坊的種種問題所以改成L1的鏈,其主要特性在於保護用戶的隱私,不只有隱藏的代幣Secret Tokens、Secret NFTs,甚至連智能合約的運作也可以隱藏起來(Secret Bridges、Secret Finance),其實現的方式是透過一種特殊的硬體TEE(Trusted Execution Environment)來運作加解密,甚至連設備管理員也無法看到其中的內容,而這就符合臨上六損這一卦的性質,需要有特別的機器(「得臣无家」),而管理員則是無法細看(「敦臨」) 從卦象來看,Secret這一年的應該會發展出新功能,也有可能是有新的合作伙伴(「得臣无家」),不過因為變卦是損卦,所以短期內的狀況會比較不好,可能遇到一些意外問題而造成一些虧損,只有經歷過這些麻煩之後才能得到穩定的長期利益,市場表現也大致是如此 要說有什麼擔憂的話,就是這一卦的表現並不是那麼嚴謹,所以隱私功能或許沒預想中的那麼好,可能出了些問題也無法好好察覺 2022年7月17日6時
今天卜問的是以太坊Layer 2之一的Skale Network(SKL幣) 卜問Skale Network一年之內的發展如何?卜得歸妹初九解 歸妹初九,歸妹以娣,跛能履,征吉。 [變卦解]初六,无咎。 Layer 2的技術並不只是專注在擴大交易量,像今天介紹的Skale Network的主要目標在於擴展以太坊的智能合約的性能,透過另外建立的Skale鏈可以以高效能和低成本來執行以太坊上的dApp,而既然著重在智能合約上,就符合「合約之卦」的歸妹卦的性質 從卦象來看,Skale Network的效能實質上並沒有很好,爻辭雖然說「征吉」,但卻是「跛能履」,使用跛腳來行走,所以難成大事,而變卦解卦也通常只是暫時解救,並非完全解決問題,這說明了Skale Network這一年應該會遇到技術上的問題,即便能解決也只是以不完全的形式去解決,因而拖累了其發展進度 而從市場表現來看,這一卦算是在近期表現會比較好的一卦,因為「跛能履,征吉」就代表沒有做好完善準備也能有點表現的性質,不過當然從長期來看會是開高走低,難以走得長遠 2022年7月16日1時 ------------------------------------------ 繼續來回顧一下Celsius的占卜結果:noise.cash/post/66j0mmvh23r65 昨天看到這則新聞: 金融時報記者:Celsius執行長背棄承諾!私挪鉅額客戶資金投入挖礦子公司(一同破產) https://www.blocktempo.com/ft-reporter-celsius-move-750-million-customer-funds-without-authorization/ 如占卜結果預測的一樣,有不光彩的事情顯露出來,不過看新聞內容所謂的承諾只是嘴巴說說的,實際上契約怎麼定的比較重要,雖然我估計應該還是會有些訴訟問題產生 當然後面應該還會如同預測所說,會繼續有些難聽的傳聞出現,Celsius如果認真地想解決的話,這位執行長可能很快就會下台
今天卜問的是去中心化交易所SushiSwap(SUSHI幣) 卜問SushiSwap一年之內的發展如何?卜得比六二坎 比六二,比之自內,貞吉。 [變卦坎]九二,坎,有險,求小得。 看資料SushiSwap是Uniswap的分枝,一開始因為被當作Uniswap的複製品所以不被看好,匿名創辦人甚至拋售手中的SUSHI幣造成大跌,後來由FTX創辦人的Sam接手主控權後才興盛起來 SushiSwap目標是新增Uniswap沒有的功能,像是SushiSwap提供了SUSHI治理代幣作為獎勵,這是Uniswap之前沒有的,而在發展初期SushiSwap甚至利用其特性來對Uniswap進行「吸血鬼攻擊」,挖走Uniswap的流動性,而這點就符合變卦爻辭的「坎,有險,求小得」,意味著利用「小得」來引誘人們去做危險的事 從卦象來看雖然有鋌而走險的感覺,不過本卦爻辭「比之自內,貞吉」顯現出穩定的性質,適合作為交易工具來使用,只要開發團隊沒亂搞,那麼就沒有太嚴重的問題,而以市場表現來看,「求小得」代表多少可以獲得一些利益,不過沒辦法期待能得到大利益 2022年7月15日3時 ----------------------------------------- 來回顧一下Celsius的占卜結果:https://noise.cash/post/66j0mmvh23r65 昨天看到這篇新聞: Celsius正式向破產法院提出「自願重組」!還清Compound債務收回近2億鎂WBTC https://www.blocktempo.com/celsius-officially-filed-bankruptcy-restructuring-in-court/ 雖然是申請破產,但和破產逃走的情況不一樣,看新聞說是要讓公司繼續正常營運,因為以現在的情況沒辦法正常營運,所以進行自願重組,除此之外之前也有在向一些機構還錢,雖然目前還不清楚一般用戶能拿回多少,但可以感覺到Celsius有在反省檢討,也準備重新進行營運,符合之前卦象的解讀 不過履上九「考祥其旋」這一卦事情發展進度往往會原地打轉,所以可以預期整個重組過程會很漫長,如果一般用戶能拿回錢的話應該也是很久之後的事情了
今天卜問的是美國經濟 卜問美國經濟一年之內的發展如何?卜得巽初六小畜 巽初六,進退,利武人之貞。 [變卦小畜]初九,復自道,何其咎,吉。 考慮到加密貨幣目前還是一個投機成份比較大的產業,所以很仰賴市場熱錢來支撐其聲勢,如果世界經濟龍頭老大的美國持續保持收起熱錢的政策的話,那麼幣市的熊市應該還會繼續一段很長的時間,剛才看到美國CPI創40年新高,前景令人擔憂,所以今天就來卜問一下 本卦是「流行」之卦的巽卦,所謂的流行就是出些宣傳命令,其他人就會跟著命令行動,符合美國政府現在一言一行都會影響到世界各國經濟的狀態,然而爻辭卻說「進退,利武人之貞」,代表美國政府現在的命令沒有統一的方向,行動優柔寡斷,大家可以回想一下去年美軍撤出阿富汗的慘況,大概就知道現在美國政府的指揮能力是怎麼樣糟糕了 所幸變卦是多少能獲得一些積蓄的小畜卦,爻辭也有云:「復自道,何其咎,吉」,意思就是經濟會慢慢重入正軌,但是既然是在家畜養的小畜卦就不要期待一些國際貿易能興盛起來,頂多就是國內經濟會好轉一點,因此整體來看市場走向會像爻辭所說那樣進進退退 而加密貨幣以目前性質來看應該要放在國際貿易經濟上,國際轉帳比較方便,但是國內消費的地方不多,從這點來看,這一年的幣市寒冬應該還會再持續下去 2022年7月14日0時
今天卜問的是DeFi項目UMA(UMA幣) 卜問UMA一年之內的發展如何?卜得未濟初六睽 未濟初六,濡其尾,吝。 [變卦睽]初九,悔亡,喪馬勿逐,自復。見惡人,无咎。 UMA和之前介紹的Synthetix有點像(https://noise.cash/post/8z9jq4md0x6z9 ),主要透過創建合成代幣來追踪某種資產的價格,並根據資產價格的漲跌來決定使用者的損益,和Synthetix的差別在於Synthetix使用其SNX代幣作為抵押品來創建合成資產,而UMA可以抵押任何加密貨幣來創建合成代幣,比如說抵押DAI來獲得aDAI,然後再用這個aDAI去鑄造「追踪黃金價格的合成代幣」 除此之外,UMA還有一個很大的特點,那就是UMA不依賴使用預言機取得外部資產的價格決定是否清算代幣發行者的資產,而是激勵代幣持有者不斷檢驗代幣發行者是否滿足抵押資格並提出清算要求,而代幣發行者也可以提出異議來讓預言機檢查價格以解決爭議,這種激勵代幣持有者去盯著發行者的方式正好符合睽卦的性質,睽卦的卦象就是同處一室之人互相仇視的樣子 從卦象來看,本卦是冒險之卦的未濟卦,可以見得UMA這一年其實沒什麼正經的計畫,就只是亂闖亂試來碰碰機會,比如到處去找合作的伙伴、金主、或合作公司,不過爻辭「濡其尾,吝」說明可能不會遇到什麼好運,通常是事事遇到阻礙 而從變卦爻辭「喪馬勿逐,自復。見惡人」來看,可能會遇到某些惡人帶來麻煩,因而損失一些利益,不過有「自復」說明也許可以有另外的補償或把損失的利益找回來,但整體來看還是弊大於利,所以市場表現不會太好 2022年7月12日22時
今天卜問的是Dogelon Mars幣(ELON幣) 卜問Dogelon Mars一年之內的發展如何?卜得旅六五遯 旅六五,射雉,一矢亡,終以譽命。 [變卦遯]九五,嘉遯,貞吉。 Dogelon Mars看名字就知道又是狗狗幣的系列,這次還把馬斯克、火星的要素又加進來,目標就像吹牛一樣,說要為航天工業和火星上提供一種可用作支付手段的加密貨幣,而這種吹牛說大話、失敗了也不負責任的滑溜性質就符合變卦遯卦 通常這個卦會因為一些事而帶來不好的名聲(「終以譽命」),雖然也有帶來好名聲的情況,不過Dogelon Mars的設定看來就是不務正業,不能期待會有什麼好事發生,有的話頂多就是炒作出一些聲勢 玩這個幣的人應該都知道風險有多大,想碰的話就自行承擔風險,這一卦基本上有失有得(「射雉,一矢亡」),能獲得多少要全靠自身的實力和運氣 2022年7月11日18時
今天卜問的是區塊鏈Horizen(ZEN幣) 卜問Horizen一年之內的發展如何?卜得隨六二兌 隨六二,係小子,失丈夫。 [變卦兌]九二,孚兌,吉,悔亡。 Horizen源自於Zcash,從歷史來說,Zcash當時有一個詬病之處:礦工的挖礦獎勵有20%會回流到創始團隊手上,所以後來出現了分叉幣Zclassic(ZCL),標榜100%的礦工獎勵,反過來說,Zclassic並沒有一個強有力的組織來主導、只能依靠社群發展,不過社群的活躍度也不強因而呈現瀕死狀態,所以後來又出現了以Zclassic為基礎的ZenCash,再到後來ZenCash改名成現在的Horizen,這就是Horizen的整個歷史,而在爻辭中有提到「係小子,失丈夫」,這就是暗示其原來基礎的Zclassic想要吸引礦工(小子)但卻失去組織性(丈夫)的性質 Horizen的本質還是匿踪幣,不過看資料目前主打的是側鏈技術,允許使用的企業公司可以開發自己的區塊鏈,然後以側鏈的形式和Horizen的主鏈進行相連和互動,以卦象來說這個方向有點像是發展錯方向的樣子(「係小子,失丈夫」),雖說如此還是有機會從一些合作的公司獲得一定的合作利益(「孚兌,吉,悔亡」),所以情況並沒有很糟,只是以這個卦來說通常只能獲得到些小利,沒有什麼大利 2022年7月10日21時
今天卜問的是Polymath(區塊鏈Polymesh、POLY幣) 卜問Polymath一年之內的發展如何?卜得否九四觀 否九四,有命无咎,疇離祉。 [變卦觀]六四,觀國之光,利用賓于王。 Polymath項目主打的是把資產代幣化,比如股票、債券、房地產、私募基金都可以轉換成代幣,並且能以低手續費來輕易買賣這些資產,當然為了讓交易合於法規,所以也會限制成只有經過驗證的使用者才能使用,相較於其他隱私性較重的加密貨幣,Polymath更傾向把一切攤開來方便監管、觀察,而這就符合觀察之卦的觀卦性質 從卦象來說,這一年的發展結果還不錯,變卦爻辭「觀國之光,利用賓于王」說明有機會和政府監管機關進行合作,讓整個系統運作可以以合法規的形式上軌道,不過因為本卦是否卦,所以一開始可能會有溝通不良的問題或是一些計畫的阻礙、法規的限制,開發團隊需要長時間的努力才能最終解決問題 2022年7月10日3時
今天卜問的是基金會APENFT(NFT幣) 卜問APENFT一年之內的發展如何?卜得革九三隨 革九三,征凶,貞厲。革言三就,有孚。 [變卦隨]六三,係丈夫,失小子。隨有求得,利居貞。 APENFT從名字來看基本上就知道是個著重在NFT上的項目,主要是為傳統頂級藝術家進軍NFT提供橋梁的藝術基金會,之前在卜問NFT時就有出現隨卦:https://noise.cash/post/mr8gjqks8m7p3 ,裡面有說人們買某種NFT只是為了用更好的價錢賣它,而不是真的想要永遠擁有它,所以符合隨卦「得失無常」的性質 從卦象來看,這一年應該會有些變革的計畫出現,不過因為時機不好,遇到熊市的狀況,所以如果沒有謹慎重新策劃的話,執行起來會出問題(「征凶,貞厲。革言三就」),一不小心就會把計畫一改再改 而從市場表現來看,爻辭「係丈夫,失小子。隨有求得,利居貞」說明還是能從一些名氣較大的作品獲利,但是名氣較小的作品反而可能帶來損失,整體來看應該還是獲利的,只是不會像牛市一樣那麼順利 2022年7月9日3時
今天卜問的是Ethereum Name Service(ENS幣) 卜問ENS一年之內的發展如何?卜得夬九二革 夬九二,惕號,莫夜有戎,勿恤。 [變卦革]六二,已日乃革之,征吉,无咎。 ENS是建立在以太坊上的去中心化域名服務,主要目標是把難記的以太坊地址轉換成以「.eth」結尾的文字域名,而這就符合革卦的「革新」性質,以新的東西覆蓋舊的東西以達成目的 從卦象來看,會有小人濫權或進行攻擊的可能性,不過爻辭「惕號,莫夜有戎,勿恤」說明只要足夠小心的戒備,那麼就能很快地解決問題,另一方面變卦爻辭「已日乃革之,征吉」則說明這一年可能會有一些變革的計畫,變革的狀況如果是挑準好的時機行動那麼結果應該是不錯 至於市場表現的話,查了一下最近的ENS新聞,看起來還不錯: 以太坊域名服務單周註冊量超10萬 https://news.cnyes.com/news/id/4908433 「000.eth」以300ETH成交,位列以ETH計價的ENS成交價第二名 https://news.cnyes.com/news/id/4906304 似乎有機構或大戶在往這方面做投資準備,時機成熟之後可能會有一波聲勢上來 2022年7月7日23時
今天卜問的是API 平台Swipe(SXP幣) 卜問Swipe一年之內的發展如何?卜得萃初六隨 萃初六,有孚不終,乃亂乃萃。若號,一握為笑,勿恤,往无咎。 [變卦隨]初九,官有渝,貞吉。出門交有功。 Swipe的主要目標是建立API平台,使得合作公司可以創建法幣和加密貨幣的Visa借記卡,並且由Swipe來承擔啟動這些計畫所需的所有監管、合規性和網路責任,而既然重心是放在Visa借記卡上,那麼目標就是讓消費者能夠方便進行各種零售交易,而所謂的「零售」則符合隨卦的「得失無常」的性質,商家或使用者往往不會長期保存某些貨幣,而是在消費時才進行轉換 從資料來看,Swipe之前就被幣安收購,在背後有很穩的靠山下基本上可以放心地發展事業,而從這一卦來看短期內可能有些計畫,而且剛推出可能就會有很好的聲勢(「官有渝,貞吉。出門交有功」),雖然本卦的爻辭透露會有些誠信問題(「有孚不終,乃亂乃萃」),不過在背後有穩定靠山的情況下,應該什麼問題都能解決,而這一年的市場表現應該也是不錯 2022年7月6日23時 ------------------------------ 因為三箭資本的破產看起來已經定案了,所以來反省一下之前的占卜:https://noise.cash/post/4rj9j6mswp4rg 之前的預測是能找得到貴人幫助,不過沒特別考慮到蹇卦這一卦的性質,蹇卦的卦主如果是走正道,則運勢才會比較好,不過也有可能會走入歪道的情況,這個時候往往會讓情況變得更加糟糕,而三箭資本玩槓桿投機玩成那樣,可以很明顯說是心術不正,所以這一卦應該要解讀成無路可逃、不得不清算變賣資產才是正確的
今天卜問的是ETH的Layer2之一的Immutable X(IMX幣) 卜問Immutable X一年之內的發展如何?卜得益初九觀 益初九,利用為大作,元吉,无咎。 [變卦觀]初六,童觀,小人无咎,君子吝。 看資料Immutable X目前主要著重在 NFT 和 Gamefi 項目上面,號稱以太坊上首個NFT擴容方案,主要目標在於實現零交易手續費、即時交易確認,而益初爻這一卦有一個性質就是「先損後益」,正是因為缺損(零手續費)所以才能讓市場大幅增益起來,所以符合其性質 從卦象來看,Immutable X的基礎實力還不夠,要把市場做大目前還看不出來有足夠的能力,所以才說「利用為大作」,這一年需要很努力去做才得到相應的成果,另一方面,從爻辭「童觀」來看,開發團隊可能有些天真,有可能訂出不切實際的計畫,實際去做了之後才知道行不通,整體來看的話,Immutable X這一年能做出多少成績就要看開發團隊有多努力 2022年7月6日0時
今天卜問的是元宇宙項目之一的Ceek VR(CEEK幣) 卜問Ceek VR一年之內的發展如何?卜得大有上九大壯 大有上九,自天祐之,吉无不利。 [變卦大壯]上六,羝羊觸藩,不能退,不能遂,无攸利,艱則吉。 Ceek VR做的就是VR平台,主要著重在音樂會、比賽上的VR體驗,看資料有跟Lady Gaga等大咖明星合作,可以見得項目方背後也算是有相當不錯的人脈和資金,這點就符合大有卦的「擁有豐富資源」的性質 從爻辭「自天祐之,吉无不利」外表來看會覺得不錯,不過這一卦通常是遇到攻擊後才能得到上天保佑,而不是什麼事都沒發生就平步青雲,所以變卦爻辭顯現了這個卦的本質:「不能退,不能遂,无攸利,艱則吉」,這代表有些計畫太過強硬而可能被卡住不動,雖說最終結果還算可以,不過遇到一些強力的阻礙應該是沒辦法避免的 而在市場表現來看,有大有卦的豐富資源加持,通常在資本市場中都會有一定興盛的能力,只要沒遇到嚴重問題,應該都能做出不錯的業績 2022年7月5日2時 -------------------------------- 來回顧一下微策略的占卜:https://noise.cash/post/3gzkj7kaj8pg5 最近有這樣的新聞: 比特幣跌破2萬!微策略再砸1000萬鎂買BTC ,但累計已虧13.9億美元 https://www.blocktempo.com/microstrategy-drops-10-million-add-480-bitcoins/ 短評 | 微策略CEO:除非比特幣跌95%,股東才要擔心;持1 BTC地址數達87.3萬「歷史新高」 https://www.blocktempo.com/deutsche-bank-bitcoin-expected-to-recover-to-28000-by-year-end/ 之前的卦象有逃避現實的傾向,果不其然不只沒賣還加碼了,CEO還一副完全不擔心的樣子,不過這種完全不給自己的退路的行事方式應該遲早會出事,如果局勢如同黑鴨大所說的那樣持續火燒連環船,那今年或明年微策略應該也有可能是被燒掉的船
今天卜問的是交易所CoinEX,聽黑鴨大說BCH/sBCH可能會另開一個中心化橋在CoinEX上,所以先來看看情況 卜問CoinEX一年之內的發展如何?卜得損上九臨 損上九,弗損,益之,无咎,貞吉。利有攸往,得臣无家。 [變卦臨]上六,敦臨,吉,无咎。 CoinEX交易所比較大的特點應該是沒有嚴格的KYC,實際註冊試過後只要綁定信箱和手機就顯示可以出金了,這點符合變卦爻辭的「敦臨」,意思是雖然有在監督,但是是用敦厚寬大的方式在監督使用者的身份 從爻辭「得臣无家」來看,開中心化橋在CoinEX的消息很有可能是真的,即使不是中心化橋也代表會建立某些新功能,或是和盟友建立一些新的合作計畫 不過因為本卦是損卦,所以短期內很容易遇到一些衰事連連的狀況,不會那麼順利,但這一卦所追求的目標在於長期的利益,因而短期的狀況不佳是可以接受的,所以如果真的建好中心化橋,那麼就可以預期能長時間穩定運轉,雖然這一卦多少會遇到一些狀況,但是至少不會像CoinFLEX那樣直接卡住很長一段時間 2022年7月4日3時
今天卜問的是去中心化交易所Balancer(BAL幣) 卜問Balancer一年之內的發展如何?卜得恒九三解 恒九三,不恒其德,或承之羞,貞吝。 [變卦解]六三,負且乘,致寇至,貞吝。 Balancer和Uniswap的功能差不多,都是使用自動做市商 (AMM) 協議來進行代幣的兌換,不過其特點就在於會針對資金池進行收益調整,透過一個叫作feeFactor的計算公式來激勵各個資金池收取較低的交易費,簡單說交易費用收太高,則資金池的提供者反而會得到較少的獎勵,而這種性質正好符合變卦爻辭的「負且乘,致寇至」(背負過多的財物則會招到搶奪) 交易所最重要的是保持穩定性,從本卦恒卦來看的確有其恒長不變的穩定性,然而爻辭「不恒其德,或承之羞」卻透露這一年的發展會遇到危險,可能因為某些事情而丟掉名聲,失去眾人的信任,而危險的事很可能就是變卦爻辭所述的「負且乘,致寇至」,因為背負了過多資金,因而遭到人搶奪攻擊或是產生某種系統難以承擔的問題 照這個卦象來看,不建議把資金放在裡面進行流動性挖礦,以免被危險的意外事件所波及到 2022年7月3日4時
今天卜問的是區塊鏈SwissBorg(CHSB幣) 卜問SwissBorg一年之內的發展如何?卜得小畜九五大畜 小畜九五,有孚攣如,富以其鄰。 [變卦大畜]六五,豶豕之牙,吉。 看資料SwissBorg的主要目標是要改變瑞士私人銀行業務,透過區塊鏈和智慧合約的技術來創造個人金融的去中心化網路,而這裡的本卦小畜的性質是「存在裡面得利」、變卦大畜的性質是「放在外面得利」,基本上就是要讓錢可以在個人金融和市場金融之間自由地移動,和SwissBorg的目標相符合 這一卦的性質通常會付出比較多的花費,但反過來說也有可能獲得很大的收穫,從資料來看SwissBorg大概會和一些瑞士銀行進行合作,所以應該不用太擔心會支撐不住花費,因此這一年的發展還算是不錯 從市場表現來看的話,要看背後的準備的本金夠不夠豐厚,因為這一卦比較像是燒錢來轉換成業績(「富以其鄰」),如果本金夠豐厚那麼自然會有很好的表現 2022年7月1日20時
今天卜問的是區塊鏈Hive(HIVE幣) 卜問Hive一年之內的發展如何?卜得蹇九三比 蹇九三,往蹇來反。 [變卦比]六三,比之匪人。 Hive是從區塊鏈steem硬分叉出來,著名的去中心化社交平台steemit就是以steem為基礎建立出來,不過後來被TRON創辦人孫宇晨給收購,因為孫宇晨一些惡劣手段上的爭議,所以Hive社群的人就決定從steem硬分叉出來,而Hive的這段歷史正好符合爻辭「比之匪人」、「往蹇來反」,也就是遇到匪人而不得不改變原本的發展方向 從卦象來看,Hive這一年還是會碰到一些不好的匪人,有可能進行惡意的操控或是攻擊,而如果有什麼發展計畫的話通常會受到阻礙而難以前進,這時可能要用不正常的手段去解決 本卦蹇卦具有錢滾錢的特性,不過依照Hive的性質來看應該不算是特別容易累積財富的項目,在熊市的情況下可能情況會更糟,所以市場表現應該不會太好 2022年7月1日1時 ----------------------------- 來回顧一下SmartBCH的占卜結果https://noise.cash/post/2g64822fm84w6 裡面預測到了資源缺乏的問題,剛好最近幾天因為CoinFLEX的問題而導致流動性不足,而這個流動性不足正是資源缺乏所顯現的結果,從爻辭「苦節」來看,這個問題在短期內不太可能解決,只能硬撐下去
今天卜問的是GameFi的Walken(WLKN幣) 卜問Walken一年之內的發展如何?卜得歸妹六五兌 歸妹六五,帝乙歸妹,其君之袂不如其娣之袂良,月幾望,吉。 [變卦兌]九五,孚于剝,有厲。 Walken簡單說就是目前Move to earn的龍頭StepN的仿盤,不過玩法有些不太一樣,玩家的走路步數會轉化成遊戲內代幣GEM,GEM可以用來升級遊戲中的角色CAThlete的能力,用這些CAThlete進行比賽獲勝才能得到WLKN代幣獎勵,這個性質就像是養女兒但卻期望從嫁娶中獲得相應的利益,所以符合歸妹卦的性質 從卦象來看,表面上看起來盛大美好(「帝乙歸妹」),彷彿可以和StepN相比,不過本質上還是跟風追求利益的仿盤,有些重要的部份並沒做得很好就急著上架了(「其君之袂不如其娣之袂良」),所以從長遠發展來看可能撐不太過熊市 變卦則是容易帶來毀壞名聲的兌卦,爻辭「孚于剝,有厲」則代表開發團隊可能有人在亂搞,情況很可能是每況愈下,雖說如此,歸妹卦是合約同盟之卦,依照這個卦的性質短期內還是能夠持續吸引人進來玩,獲得一些短期利益,不過不要期待會有什麼長期利益 2022年6月30日3時 -------------------------------- 回顧一下Arbitrum的占卜:https://noise.cash/post/mpkw569c8m7p3 剛看到這則新聞: Arbitrum宣布將暫停奧德賽活動,暫定於Nitro發布後恢復 https://news.cnyes.com/news/id/4904328 聽說暫停活動的原因是為了解決L2 GAS比ETH主網還貴的尷尬情況: https://noise.cash/post/9mp2730d0z5m6 雖然還不算是完整應驗卦象的情況,不過這已經表現出豐卦的「試煉」的性質,往後還會有很多試煉在等著Arbitrum去解決,而當然從卦象來看沒那麼容易能夠解決成功