想了解 AO 上應用的合約運行機制嗎?那麼來抓取合約代碼一探究竟吧。用一個 python 小程序,輕鬆獲取指定 Process 的合約。

作者: txohyeah

審閱:outprog

來源:內容公會 - 新聞

AO 簡介

什麼是 AO?

AO 測試網發佈已經有小半年了,AO 的內容也有很多,本文的內容主要聚焦 Process 和智能合約,包括 AO 是什麼,Process 是什麼,Process 的生命週期。最後重點介紹下如何查看 Process 的合約代碼。

AO 是 Arweave 在完善分佈式存儲基礎上,進一步發展出的計算功能,旨在實現全面的去中心化應用支持,與以太坊先計算後存儲的發展路徑相對應。簡單來說,AO 代表了 Arweave 平臺上的智能合約或計算能力,是在其永久存儲解決方案之上的邏輯層擴展。

AO 由三個單元組成,MU / SU / CU

MU:接收到用戶發送的消息,以確保它們經過簽名。

SU:對消息進行時間戳和排序,然後捆綁併發布到 Arweave。SU 也是我們今天會用到的主角,後面會在查看合約時,起到了重要的作用。

CU:處理消息並計算出結果。

什麼是 AO 上運行的 Process?

AO 本質上是基於一個 Data Protocol 構建的超級並行計算機,其中 Data 的存在形式是 AO 中定義的基本元素 Message。那麼 Process 在這其中扮演着處理 Message 的重要角色,是處理 AO 上消息的基本單元。Process 運行在 CU 上,可以看成是 CU 上的一個虛擬機。因此,Process 包含基本的能力就是在網絡內接收和發送消息。然後開發者通過爲 Process 添加 handler 的方式,爲 Process 構建消息處理的能力。後面要講到的合約,其實就是通過發送一條消息到 Process,再通過內置的 _eval handler 部署的。其中添加的 handler 可以理解爲合約的消息處理函數。

Process 的生命週期

如果要在我們現有的世界中找到一個類比,那麼我認爲 docker 中容器(Container)可以很好的讓人對比理解 Process。下面我會藉助 docker 中 Container 的生命週期類比下 Process 的生命週期。

我們都知道 docker 中 Container 的創建會依賴一個鏡像(Image),比如根據 mysql 的 Image 創建一個 mysql 的 Container,而後就可以在這個容器上調用 mysql 的服務了。AO 中的 Process 也是一樣,Process 的創建依賴於 Module,並且也會存在不同功能的 Module,有最簡單的 Module,有支持定時任務的 Module,也有包含 sqlite 的 Module。目前已經有上百個 Module,可供開發者選擇去創建自己的 Process。另外,自己也可以去製作自定義的 Module。相信在不久的將來,也會出現支持 GPU 的 Module,支持各種 AI 能力的 Module。

AO 中的 Process 也存在與 docker 中 Container 不一樣的地方。Docker 中的 Container 支持啓動、停止、刪除等各種動作。目前在 AO 的 Process 中是沒有這些操作的,畢竟在去中心化應用的世界中,這些由中心化個人控制的功能就顯得很不融洽了。在 AO 中 Process 的運行完全取決於 Process 自己的價值,如果有足夠的價值,那麼肯定會有更多的 CU 願意去運行它,相反,一個 Process 如果沒有價值,就沒有 CU 願意去運行它,那麼這個 Process 就將默默的消失。

Eval 函數與 AO 合約部署

什麼是 AO 合約?對比以太坊的智能合約。AO 上運行的 Process 中的 Lua 代碼可以近似的看成智能合約。

我們創建 Process 時,加載的每一個 Module 都會帶有兩個默認的 handler(handler 可以被理解爲對其他 Process 開放的函數),其中一個函數就是 _eval handler。這個 handler 的主要功能就是運行 Lua 代碼。比如你在 aos 中輸入1+1,返回一個2,就是通過這個 handler 處理的。那麼部署合約實際上,就是給 Process 發送消息,通過 _eval handler 給這個 Process 中添加可以處理業務邏輯的自定義 Handler。

其中需要注意一點,請看下方代碼。這是官方開源 AO 項目中 process.lua 中的代碼段落。只有當消息的發送者與 Process 的 Owner(Owner爲創建合約時的錢包地址)一致時,才能執行 _eval handler。也就是說,如果 Owner 被設置爲 nil 時(即把該 Process 設置爲沒有 Owner),那麼這個 Process 中的合約就成爲了一個沒有人可以再修改的合約了。

另外,因爲 AO 實際上是基於存儲的共識範式(SCP,Storage-based Consensus Paradigm)構建的,所以運行的合約必定是可以在“存儲共識”上找到,即在 Process 中運行的所有消息,包括通過 _eval handler 部署的合約代碼,都存在了 Arweave 上。因此,任何人都可以在該“存儲共識”上找到合約代碼。

查看合約

那麼來到了今天的主題,究竟如何找到合約代碼呢?下面我介紹下兩種方法,並給出一份抓取合約的 Python 程序。

Arweave

第一種方法當然就是直接在 Arweave 上查詢(可以使用graphql https://arweave.net/graphql)。這種方法會要求在數據打包到 Arweave 後纔能有用。

SU - 瀏覽器

第二種就是今天主要介紹的辦法。由於所有的數據都會經過 SU 上鍊,因此也可以在 SU 上查詢。個人認爲每個 SU 會在自己本地有一份緩存,緩存了由自己上鍊的數據,因此就可以根據查詢 SU 找到對應的合約代碼。首先,可以根據瀏覽器輸入地址直接查詢。但是該方法的缺點也很明顯:1. 有些 Process 發送和接受的消息量巨大,因此上鍊的數據量也巨大。但是瀏覽器可以加載的數據有限,經常會出現瀏覽器崩潰。 2. 很難從海量的數據中過濾出自己想要的合約數據。

如下圖,展現的是兩個時間戳內,process id 爲 m3PaWzK4PTG9lAaqYQPaPdOcXdO8hYqi5Fe9NWqXd0w 的進程(AO token 進程)的所有消息。

SU - sdk

這邊我寫了一個小程序,藉助業內大佬基於 python 寫的一個 ao 的 sdk,把 Action 爲 Eval 的消息過濾出來。(Action 爲 Eval 的消息,即爲所有由 _eval handler 處理的消息,也包括加載的合約代碼。)如下圖是我從SU 上面抓取的消息,其中 data 字段中的內容就是經過字符轉義的一份合約代碼。當然抓取的消息也會包含非部署合約代碼的內容,比如執行個 1 + 1 等。但是過濾以後的消息數量已經不多了,完全可以人工選取出來合約的代碼。

程序已經開源,這裏是 github 的地址:https://github.com/txohyeah/ao-sc

AO token 合約

那麼讓我們激動的來看看 ao token 的合約代碼。(抓下來的合約代碼也會一併放在開源的代碼倉庫中)

首先,初始化狀態時,定義了 TotalSupply = "21000000000000000000" 與比特幣一致的發行量。

Denomination = Denomination or 12 還定義了小數點爲12位。

定義了在 100000 個區塊產生之前,如果執行 transfer 函數,則直接返回 "Transfer is locked"。

由於五分鐘產生一個區塊,那麼 100000 個區塊就大約到了明年 2 月份了。

還有更多相關的信息,我就不囉嗦了。大家可以愉快的瀏覽這份經典的AO合約。

程序使用說明

上面我介紹了抓取的合約代碼,接下來我簡單介紹下這個程序。很簡單,相信不懂代碼的人也可以輕鬆使用。

第一步,安裝 python 3.12 版本。程序是 python 寫的,安裝 python 是必須的。

第二步,安裝所需要的包。本程序依賴業內大佬的 sdk,依賴於 everpay。

第三步,修改 fetch_sc_record.py 中的 start_time / end_time / process。並執行 fetch_sc_record.py。

start_time 和 end_time 是你需要抓取的時間段。process 是你需要抓取合約的 Process 的 id。

第四步,對應的 Eval 消息,就會出現在 msg_eval.json 的文件中了。再瀏覽其中的消息,就可以找到你需要的合約代碼啦!

PS:也需要和運行 aos 一樣。設置 HTTPS_PROXY。

🏆 “捉蟲”有獎:在本文發現錯字、病句、描述有誤,點我報告,可得激勵。

免責聲明:本文不代表 PermaDAO 的觀點或立場。PermaDAO 不提供投資建議,亦不爲任何項目背書。請讀者遵守所在國法律,合規進行 Web3 活動。

🔗 關於 PermaDAO:Website | Twitter | Telegram | Discord | Medium | Youtube