Truffle

如何在測試合約時注入假值?

  • January 25, 2022

我習慣了 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);
   // ....
 }
}

變更摘要。

  1. _oracle- 風格
  2. public- 可發現狀態
  3. immutable``constant- 與部署時效果相同但更靈活
  4. constructor()- 設置值

你可以在本地鍊或網路分叉上執行測試,創建許多帳戶,甚至使用免費資金和模擬,但你不能強迫合約做一些它沒有被編碼做的事情。無法覆蓋該硬編碼地址或臨時更改函式中的邏輯。

所提出的方法提供了與 a 相同的效率constant和相同的不變性,以及一種使用它必須在主網上的地址來確認正確部署的方法。你甚至可以考慮嵌入註釋來記錄你的意圖——在不同的測試網和主網上“正確”的預言機地址。

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/115142