Truffle
如何在測試合約時注入假值?
我習慣了 Java 模擬,在那裡我可以訪問和修改私有值。由於我們在本地機器上並擁有乙太坊節點,我們也可以這樣做。
我的問題是我想修改所需的地址。只有我的 Oracle 有權呼叫函式,我希望我的測試能夠這樣做。
contract CodeFanSites { address private constant _Oracle = 0xf17f52151EbEF6C7334FAD080c5704D77216b732; function addSite(address payable user, string memory domain) external { require(msg.sender == _Oracle); // .... } }
我的測試,使用 truffle :
contract("CodeFanSites", (accounts) => { let [nik, oracle] = accounts; it("should be able to add a new domain site", async () => { const contract = await CodeFanSites.new(); console.log({balance: sites, accounts, nik}); // I need before here to modify the _Oracle private address in the contract const result = await contract.addSite(oracle, "site.com"); // .... })
如何在測試中呼叫函式
_Oracle
之前更改合約中的私有地址?addSite()
請注意,
_Oracle
不必保持不變,它可能只是私有的。我不希望任何人能夠更改此值,除非在測試時。
簡短的回答是,你不能在設計契約時考慮到測試計劃。
在我看來,問題的根源在於硬編碼的預言機地址。這可能是抽象的,允許在測試期間使用 oracle 模擬。考慮:
contract CodeFanSites { address public immutable _oracle; constructor(address oracle) { _oracle = oracle; } function addSite(address payable user, string memory domain) external { require(msg.sender == _oracle); // .... } }
變更摘要。
_oracle
- 風格public
- 可發現狀態immutable``constant
- 與部署時效果相同但更靈活constructor()
- 設置值你可以在本地鍊或網路分叉上執行測試,創建許多帳戶,甚至使用免費資金和模擬,但你不能強迫合約做一些它沒有被編碼做的事情。無法覆蓋該硬編碼地址或臨時更改函式中的邏輯。
所提出的方法提供了與 a 相同的效率
constant
和相同的不變性,以及一種使用它必須在主網上的地址來確認正確部署的方法。你甚至可以考慮嵌入註釋來記錄你的意圖——在不同的測試網和主網上“正確”的預言機地址。希望能幫助到你。