如何使用Rust直接編譯單個(gè)的Solidity合約
使用Rust直接編譯單個(gè)的Solidity合約
前言
我們知道,我們平常開發(fā)Solidity智能合約時(shí)一般使用Hardhat框架,但是如果你是一個(gè)Rustacean (這是由 “Rust” 和 “crustacean” -甲殼類動(dòng)物 結(jié)合而來的俏皮稱呼),也許你會(huì)使用Foundry框架進(jìn)行開發(fā)。開發(fā)好了之后,我們要編寫相關(guān)應(yīng)用怎么辦?通常的做法是將編譯好的合約字節(jié)碼和ABI復(fù)制到其它項(xiàng)目中去,然后使用各種框架來編寫我們的Dapp。
但是這里有一個(gè)問題,如果合約只是簡(jiǎn)單的合約,或者是一個(gè)flatten之后的合約,如果有任何修改,你都必須在Hardhat或者Foundry中進(jìn)行重新編譯,然后重復(fù)復(fù)制到Dapp目錄(偷懶的做法是使用一個(gè)sh 腳本自動(dòng)去做這些事)。那么,作為一個(gè)Rustacean來講,你肯定在想,能否在我的Dapp中使用Rust語言來直接編譯這個(gè)合約呢?答案是肯定的。
這樣做的目的是為我們節(jié)省不少工序,如果只是一個(gè)簡(jiǎn)單的沒有外部依賴的合約,或者是一個(gè)Flatten后的合約,我們直接在Dapp目錄進(jìn)行開發(fā)和編譯及使用其它庫進(jìn)行交互,不必重新建立hardhat或者foundry工程。
但是這是有前提的,我們直接使用Rust編譯并不會(huì)自動(dòng)查找它的外部依賴,因此這是我說的只能編譯簡(jiǎn)單合約或者flatten合約的原因。
預(yù)備知識(shí)
Rust 語言本身無法編譯Solidity或者Vyper智能合約,因此它還是得調(diào)用第三方編譯工具進(jìn)行。通常這個(gè)工具為solc。其原理就是Rust調(diào)用solc,再由solc來編譯合約。
但是Rust調(diào)用solc這一步已經(jīng)有第三方庫抽象好了,我們不必手動(dòng)去實(shí)現(xiàn)了。
在我們的示例中,我們使用 foundry-compilers
這個(gè)crate
來調(diào)用solc
進(jìn)行編譯,它其實(shí)是Foundry
內(nèi)部工具的一部分。
準(zhǔn)備工作
上面提到了,還是得第三方編譯工具。因此我們得安裝solc,具體方法為:
brew install solc-select solc-select install 0.8.24 solc-select use 0.8.24
示例
運(yùn)行cargo new sol_demo
來新建一個(gè)rust 工程
在項(xiàng)目根目錄下建立contracts
目錄,這是hardhat框架常用的源文件目錄。
在contracts
目錄下新建Counter.sol
,內(nèi)容如下:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract Counter { uint256 public number; function setNumber(uint256 newNumber) public { number = newNumber; } function increment() public { number++; } }
在Cargo.toml
中添加如下依賴
[dependencies] foundry-compilers = "0.11.0"
將main.rs
替換為如下內(nèi)容:
use foundry_compilers::{Project, ProjectPathsConfig}; use std::path::Path; use std::env; fn main() { // 這個(gè)環(huán)境變量會(huì)識(shí)別為運(yùn)行cargo的項(xiàng)目根目錄 let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); // configure the project with all its paths, solc, cache etc. let project = Project::builder() .paths(ProjectPathsConfig::hardhat(Path::new(&cargo_manifest_dir)).unwrap()) .build(Default::default()) //Default::default()這里其實(shí)返回的是MultiCompilers,可以編譯vyper和solidity .unwrap(); // 這里也可以使用compile()函數(shù)編譯contracts目錄下的所有文件,有外部依賴的得提前導(dǎo)入 let output = project.compile_file("contracts/Counter.sol").unwrap(); // 如果有任何錯(cuò)誤,panic output.succeeded(); println!("Compilation succeeded."); // Tell Cargo that if a source file changes, to rerun this build script. // project.rerun_if_sources_changed(); }
打開終端,在項(xiàng)目根目錄下運(yùn)行cargo run
,得到Compilation succeeded.
輸出。
同時(shí)查看項(xiàng)目根目錄,會(huì)發(fā)現(xiàn)多了artifacts
和cache
目錄,如下圖所示:
真正使用時(shí),你其實(shí)是另外起一個(gè)bin目錄,在這里面做編譯工作,而主main.rs
一般做交互工作。
到此這篇關(guān)于如何使用Rust直接編譯單個(gè)的Solidity合約的文章就介紹到這了,更多相關(guān)Rust Solidity合約內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解
這篇文章主要為大家介紹了Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Rust調(diào)用Windows API 如何獲取正在運(yùn)行的全部進(jìn)程信息
本文介紹了如何使用Rust調(diào)用WindowsAPI獲取正在運(yùn)行的全部進(jìn)程信息,通過引入winapi依賴并添加相應(yīng)的features,可以實(shí)現(xiàn)對(duì)不同API集的調(diào)用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11Rust中的方法與關(guān)聯(lián)函數(shù)使用解讀
在Rust中,方法是定義在特定類型(如struct)的impl塊中,第一個(gè)參數(shù)是self(可變或不可變),方法用于描述該類型實(shí)例的行為,而關(guān)聯(lián)函數(shù)則不包含self參數(shù),常用于構(gòu)造新實(shí)例或提供一些與實(shí)例無關(guān)的功能,Rust的自動(dòng)引用和解引用特性使得方法調(diào)用更加簡(jiǎn)潔2025-02-02