如何使用Rust直接編譯單個的Solidity合約
使用Rust直接編譯單個的Solidity合約
前言
我們知道,我們平常開發(fā)Solidity智能合約時一般使用Hardhat框架,但是如果你是一個Rustacean (這是由 “Rust” 和 “crustacean” -甲殼類動物 結(jié)合而來的俏皮稱呼),也許你會使用Foundry框架進行開發(fā)。開發(fā)好了之后,我們要編寫相關(guān)應(yīng)用怎么辦?通常的做法是將編譯好的合約字節(jié)碼和ABI復(fù)制到其它項目中去,然后使用各種框架來編寫我們的Dapp。
但是這里有一個問題,如果合約只是簡單的合約,或者是一個flatten之后的合約,如果有任何修改,你都必須在Hardhat或者Foundry中進行重新編譯,然后重復(fù)復(fù)制到Dapp目錄(偷懶的做法是使用一個sh 腳本自動去做這些事)。那么,作為一個Rustacean來講,你肯定在想,能否在我的Dapp中使用Rust語言來直接編譯這個合約呢?答案是肯定的。
這樣做的目的是為我們節(jié)省不少工序,如果只是一個簡單的沒有外部依賴的合約,或者是一個Flatten后的合約,我們直接在Dapp目錄進行開發(fā)和編譯及使用其它庫進行交互,不必重新建立hardhat或者foundry工程。
但是這是有前提的,我們直接使用Rust編譯并不會自動查找它的外部依賴,因此這是我說的只能編譯簡單合約或者flatten合約的原因。
預(yù)備知識
Rust 語言本身無法編譯Solidity或者Vyper智能合約,因此它還是得調(diào)用第三方編譯工具進行。通常這個工具為solc。其原理就是Rust調(diào)用solc,再由solc來編譯合約。
但是Rust調(diào)用solc這一步已經(jīng)有第三方庫抽象好了,我們不必手動去實現(xiàn)了。
在我們的示例中,我們使用 foundry-compilers這個crate來調(diào)用solc進行編譯,它其實是Foundry內(nèi)部工具的一部分。
準(zhǔn)備工作
上面提到了,還是得第三方編譯工具。因此我們得安裝solc,具體方法為:
brew install solc-select solc-select install 0.8.24 solc-select use 0.8.24
示例
運行cargo new sol_demo 來新建一個rust 工程
在項目根目錄下建立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() {
// 這個環(huán)境變量會識別為運行cargo的項目根目錄
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()這里其實返回的是MultiCompilers,可以編譯vyper和solidity
.unwrap();
// 這里也可以使用compile()函數(shù)編譯contracts目錄下的所有文件,有外部依賴的得提前導(dǎo)入
let output = project.compile_file("contracts/Counter.sol").unwrap();
// 如果有任何錯誤,panic
output.succeeded();
println!("Compilation succeeded.");
// Tell Cargo that if a source file changes, to rerun this build script.
// project.rerun_if_sources_changed();
}打開終端,在項目根目錄下運行cargo run,得到Compilation succeeded.輸出。
同時查看項目根目錄,會發(fā)現(xiàn)多了artifacts和cache目錄,如下圖所示:

真正使用時,你其實是另外起一個bin目錄,在這里面做編譯工作,而主main.rs一般做交互工作。
到此這篇關(guān)于如何使用Rust直接編譯單個的Solidity合約的文章就介紹到這了,更多相關(guān)Rust Solidity合約內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解
這篇文章主要為大家介紹了Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Rust調(diào)用Windows API 如何獲取正在運行的全部進程信息
本文介紹了如何使用Rust調(diào)用WindowsAPI獲取正在運行的全部進程信息,通過引入winapi依賴并添加相應(yīng)的features,可以實現(xiàn)對不同API集的調(diào)用,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-11-11
Rust中的方法與關(guān)聯(lián)函數(shù)使用解讀
在Rust中,方法是定義在特定類型(如struct)的impl塊中,第一個參數(shù)是self(可變或不可變),方法用于描述該類型實例的行為,而關(guān)聯(lián)函數(shù)則不包含self參數(shù),常用于構(gòu)造新實例或提供一些與實例無關(guān)的功能,Rust的自動引用和解引用特性使得方法調(diào)用更加簡潔2025-02-02

