Ich habe einen einfachen Vertrag, der ein festlegt, owner
wenn der Vertrag initialisiert wird, aber ich habe Probleme zu verstehen, warum er sich unter bestimmten Umständen ändert.
Ich habe 3 Möglichkeiten ausprobiert, ein Array zu initialisieren und festzulegen:
Die Fälle 1 und 2 verhalten sich wie erwartet, aber Fall 3 ändert schließlich den owner
Wert und führt dazu, dass Tests fehlschlagen. Kann jemand Einblick in dieses Verhalten geben?
Intelligenter Vertrag:
pragma solidity ^0.4.4;
contract WeirdCase {
address internal owner;
uint256[] newArray;
constructor() {
owner = msg.sender;
}
function someMethod1() external {
uint256[] memory newArray = new uint256[](10);
for (uint256 i = 0; i < 10; i++) {
newArray[i] = i;
}
}
function someMethod2() external {
for (uint256 i = 0; i < 10; i++) {
newArray.push(i);
}
}
function someMethod3() external {
uint256[] storage weirdArray;
for (uint256 i = 0; i < 10; i++) {
weirdArray.push(i);
}
}
function getOwner() view returns(address) {
return owner;
}
}
Testfall:
var WeirdCase = artifacts.require("./WeirdCase.sol");
contract('WeirdCase', function(accounts) {
let weirdCase;
beforeEach(async () => {
weirdCase = await WeirdCase.new();
});
it("Case 1: succeeds", async function () {
let beforeOwner = await weirdCase.getOwner();
await weirdCase.someMethod1();
let afterOwner = await weirdCase.getOwner();
assert.equal(beforeOwner, afterOwner);
});
it("Case 2: succeeds", async function () {
let beforeOwner = await weirdCase.getOwner();
await weirdCase.someMethod2();
let afterOwner = await weirdCase.getOwner();
assert.equal(beforeOwner, afterOwner);
});
/*
* DON'T KNOW WHY THIS FAILS!!!
*/
it("Case 3: not sure why this fails", async function () {
let beforeOwner = await weirdCase.getOwner();
await weirdCase.someMethod3();
let afterOwner = await weirdCase.getOwner();
assert.equal(beforeOwner, afterOwner);
});
});
Diese Zeile ist der Schlüssel:
uint256[] storage weirdArray;
Sie definieren weirdArray
als Zeiger auf ein Array im Speicher, aber Sie zeigen nie auf ein Array im Speicher. Daher weirdArray
wird der Array-Zeiger als initialisiert 0x00
.
Dadurch .push()
schreibt der in den Speicherort 0x00
, da die push
Methode davon ausgeht, dass dort das Array gespeichert ist. 0x00
passiert, wo der Compiler Ihre owner
Zustandsvariable platziert hat.
Kryptoninja