Solidity

訪問其他合約中的狀態變數

  • March 11, 2022

我試圖在契約中添加方法,但它變得如此之大,以至於我無法用松露來部署它。現在我需要創建一個將被呼叫的 otehr 合約而不是原始合約來處理儲存在原始合約中作為狀態變數的數據。

我要處理的變數是一個映射。

我正在嘗試做這樣的事情:

contract Original {

mapping(bytes32 => Person) private Persons;

/* many structs and methods here */
}

contract SecondContract {
  function processdata(){
    /* here i want to process the data stored in the mapping in the first contract */
  }
}

我如何獲得兩個契約之間的連結並能夠處理該數據?

如果我理解正確,您只想訪問儲存在Original. 如果是這種情況,您可以執行以下操作:

contract Original {
 mapping(bytes32 => Person) public persons;
}

contract SecondContract {
 Original original;

 function SecondContract(address ofOriginalContract) {
   original = Original(ofOriginalContract);
 }

 function processData(bytes32 someBytes) {
   Person entry = original.persons[someBytes];
   // do something with entry
 }
}

請注意,我製作persons了一個public映射,因此我們可以從另一個合約訪問它。

放大@Travis的答案。

這條線

Original original;

增加了相當大的尺寸,SecondContract因為它包含 Original.

這是一個可以通過界面解決的單獨問題。SecondContract不需要完整的字節碼Original。這是重複和不必要的。它只需要實例的函式簽名和地址即可與之對話。

有一些棘手的繼承和類型轉換問題需要解開,以便SecondContract可以繼承最小可能Original的表面區域表示(但不是工作程式碼),並且兩個契約可以在Person. 我決定為你試一試。您可以從中推斷出更複雜的情況。

SecondContract小得多,因為interfaces它繼承的永遠不會變得很大。

pragma solidity 0.8.1;

interface Types {
 struct Person {
   uint age;
   string name;
 }    
}

interface IOriginal is Types {
 function persons(bytes32) external view returns(uint, string memory);
}

contract Original is IOriginal {
 mapping(bytes32 => Person) public override persons;
}

contract SecondContract is Types {
 IOriginal original;

 constructor(address ofOriginalContract) {
   original = IOriginal(ofOriginalContract);
 }

 function processData(bytes32 someBytes) public {
   (uint age, string memory name) = original.persons(someBytes);
   // do something with entry
 }
}

如果function persons()返回 aPerson而不是 the 中的成員會更令人滿意,struct但我沒有讓它工作。也許一個善良的靈魂會為此提出解決方案。

希望能幫助到你。

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