Angenommen, ich möchte meine eigene Version einer suicide
Vertragsfunktion mit erweiterter Funktionalität implementieren. Genauer gesagt möchte ich den internen Speicherstand des Vertrags auf eine neue Vertragsadresse kopieren, bevor ich ihn ungültig mache. Beispielsweise habe ich möglicherweise eine Zuordnung, die die Token der Benutzer speichert, und ich möchte, dass diese Informationen im neuen Vertrag verfügbar sind. Ich weiß, dass die delegatecall
Funktion anderen Verträgen den Zugriff auf die Speicherung des Vertrags ermöglichen kann, aber was ist, wenn ich den ursprünglichen Vertrag beenden möchte.
Eine Möglichkeit, wie ich dachte, dies zu tun, besteht darin, dem Vertrag eine Funktion wie die folgende hinzuzufügen, in der ich explizit schreibe, welche Daten mit der Aufruffunktion kopiert werden sollen:
pragma solidity ^0.4.2;
contract Sample {
uint public data;
function setData(uint data_){
data = data_;
}
function mySuicide(address newContract) {
newContract.call(bytes4(sha3("setData(uint256)")), _n);
suicide(newContract);
}
}
contract NewContract {
uint public data;
function setData(uint data_){
data = data_;
}
}
Das obige Beispiel ist jedoch einfach, da es nur eine einfache Zahl übergibt.
Also meine Fragen sind:
Ja, das ist möglich, wenn Sie Ihren Vertrag upgradefähig machen.
Eine kurze Beschreibung des Ansatzes - Erstellen Sie die Vertragsdatenschicht als separaten Vertrag (DataStore) und gestalten Sie den Hauptvertrag so, dass Sie immer dann, wenn Sie Ihren Vertrag beenden, Ihren alten DataStore mit dem neuen Vertrag verknüpfen können.
Sie können diesen Blog von einem meiner Kollegen lesen , der die Aufrüstbarkeit von Smart Contracts beschreibt.
Sie können sich auch dieses Repo als Referenz ansehen , der Hauptvertrag hier ("Organization.sol") ist aktualisierbar.
Ich habe den Ansatz gesehen, die Daten vom Funktionsvertrag zu trennen. Auf diese Weise können Sie die Daten zwischen Verträgen teilen, die sie verwenden möchten.
Sie müssten Code in Ihren Vertrag und Datenvertrag schreiben, damit Sie als Eigentümer einen Vertragszugriff auf Ihre Daten genehmigen könnten.
contract MyDataContract {
address contractOwner = msg.sender;
mapping(address => bool) approvedAccess;
mapping(address => bytes) dataMap;
function approveAccess(address _addressToApprove) {
require(msg.sender==contractOwner);
approvedAccess[_addressToApprove] = true;
}
function getData(address _userAddressData) returns(bytes data) {
require(approvedAccess[msg.sender]);
data = dataMap[_userAddressData];
}
function setData(address _userAddressData, bytes data) {
require(approvedAccess[msg.sender]);
dataMap[_userAddressData] = data;
}
}
contract MyConsumerContract {
address contractOwner;
MyDataContract dataContract;
function MyConsumerContract(address _dataContract) {
contractOwner = msg.sender;
dataContract = MyDataContract(_dataContract);
}
function doSomething() {
bytes data = dataContract.getData(msg.sender);
...
dataContract.setData(msg.sender, data);
}
}
Sie können den Datenvertrag natürlich nach Belieben strukturieren und für bestimmte Daten feinere Details in Gettern und Settern angeben. Aber jetzt können Sie die Daten mit anderen Verträgen teilen, selbst nachdem Sie einen Vertrag zerstört haben, der früher darauf zugegriffen hat.
Ian Pilipsky