Array als ersten Parameter in web3.js übertragen

Wenn ich solide in Kombination mit web3.js entwickle, habe ich in letzter Zeit ein Problem. Ich erstelle unten einen Vertragscode

//setContractDetail(index,bool isConsentItem,uint8[] detailItems)
function setContractDetail(uint8 index,bool isConsentItem,uint8[] detailItems) public checkOwner{
    consentForm.items[index].isConsent= isConsentItem;
    consentForm.items[index].itemDetail = detailItems;
    /* emit SetContractDetailEvent(msg.sender,index,isConsentItem,detailItems,now); */
}
function setContractDetail2(uint8 index,bool isConsentItem) public checkOwner{
    consentForm.items[index].isConsent = isConsentItem;
}
function setContractDetail3(uint8[] index,bool isConsentItem,uint8[] detailItems) public checkOwner{
    for(uint i=0;i<index.length;i++){
        uint pointer = index[i];
        consentForm.items[pointer].isConsent= isConsentItem;
        consentForm.items[pointer].itemDetail = detailItems;
    }
    /* emit SetContractDetailEvent(msg.sender,index,isConsentItem,detailItems,now); */
}
function setContractDetail4(bool isTest,uint8[] index,bool isConsentItem,uint8[] detailItems) public checkOwner{
    for(uint i=0;i<index.length;i++){
        uint pointer = index[i];
        consentForm.items[pointer].isConsent= isConsentItem;
        consentForm.items[pointer].itemDetail = detailItems;
    }
    /* emit SetContractDetailEvent(msg.sender,index,isConsentItem,detailItems,now); */
}

Wenn ich den ersten Parameter als Array (setContractDetail3) übergebe, erhalte ich immer eine Fehlermeldung - ERROR Error: Error: Gas Required Excess Allowance or Always Failure Transaction . Wenn ich jedoch einen Nicht-Array-Wert als ersten Parameter einstelle, wird der Funktionsaufruf gut ausgeführt. Weiß jemand, was der Grund für dieses Problem ist?

ps Ich konnte den Remix erfolgreich kompilieren, aber nachdem ich den Vertrag in der Geth-Konsole festgelegt und eine Verbindung mit web3.js hergestellt habe, schlägt es letztendlich fehl.

Haben Sie das Gas und den Gaspreis beim Aufrufen der Smart-Contract-Methode festgelegt?
Ich verwende "Mycontract.methods.mymethod(parms).estimateGas({from:account}).then()", um meinen Gaswert einzurichten. Andererseits setze ich meinen gasPrice auf 0 (ich verwende geth, um -gasPrice 0 einzurichten, wenn ich die Konsole aktiviere).
Ich weiß immer noch nicht, was der Grund für den Fehler ist; aber Ihr geschätzter Gasanruf wie dieser estimateGas({from:account})ist nicht ausreichend, da ihm viele Informationen zum Schätzen des Gases fehlten. Sie sollten wie unten genügend Informationen bereitstellen
``` // CallMsg enthält Parameter für Vertragsaufrufe. type CallMsg struct { From common.Address // der Absender der 'Transaktion' To *common.Address // der Zielvertrag (nil für die Vertragserstellung) Gas uint64 // wenn 0, wird der Anruf mit nahezu unendlich Gaspreis ausgeführt * big.Int // wei <-> Gasaustauschverhältnis Wert *big.Int // wei-Menge, die zusammen mit den Anrufdaten gesendet wird []Byte // Eingabedaten, normalerweise ein ABI-codierter Methodenaufruf } ```

Antworten (2)

Es ist möglich, dynamische Arrays als Funktionsargument zu verwenden, indem ABIEncoderV2 für eine solidity-Funktion verwendet wird.

Weitere Informationen finden Sie in der folgenden Github-Ausgabe und im folgenden Blog -

https://github.com/ethereum/solidity/issues/2708

https://blog.ricmoo.com/solidity-abiv2-a-foray-into-the-experimental-a6afd3d47185

Die Verwendung mehrerer dynamischer Arrays als Argument kann jedoch ein weiteres Problem darstellen, da in Java ein Argument mit variabler Länge das letzte Argument einer Funktion sein muss und die Verwendung mehrerer Argumente mit variabler Länge in derselben Funktion nicht zulässig ist.

Ich hoffe es hilft.

Hier gilt der Fehler , dass die Transaktion immer fehlschlägt . Wenn Sie ein Array als Wert consentForm.itemsübergeben, sucht die Transaktion beispielsweise nach "randomStringThatIUsedToNameTheFirstItemInMyArray", und vergleicht es mit was auch immer, es sei denn, die Struktur von ist genau identisch mit dem übergebenen Array items[0] wird bezeichnet als. Dies wird wahrscheinlich fehlschlagen und Ihre Funktion wird in einer Schleife stecken bleiben – dh immer fehlschlagende Transaktionen .

Abgesehen davon würde ich den Vertrag umstrukturieren, da solche Schleifen immer sind

a) riskant b) gaslastig

...und im Falle eines solchen Fehlers wahrscheinlich einen Try/Catch-Block in der Schleife verwenden.