Как имитировать изменение баланса токенов ERC20 с помощью Ethereum State Override?

Я пытаюсь смоделировать изменение баланса токенов ERC20, используя функцию Ethereum State Override. Я внедрил код контракта токена в EVM и использовал State Override для изменения баланса целевой учетной записи. Однако результат запроса баланса целевой учетной записи всегда возвращает 0, независимо от того, как я настраиваю свой код.

Я пробовал разные методы, в том числе использовал другой поддельный код, модифицировал разные переменные состояния и т. д. Однако результат всегда неверен.

Я хотел бы знать, где я ошибаюсь, или есть ли другой способ использовать State Override для имитации изменения баланса токена ERC20?

Я пробовал использовать следующий код с изменением баланса USDT, но не работал:



(async () => {
    const Web3 = require('web3');
    const web3 = new Web3('http://192.168.50.159:7546'); 

    const targetAddress = '0xb7BF3e961645b8ebB75A622A07983335B61cf5c0'; // replace with the target account address
    const usdtContractAddress = '0xdac17f958d2ee523a2206206994597c13d831ec7'; //  USDT contract address
    const fakeUsdtCode = '0x606060405260008054600160a060020a03191673ffffffffffffffffffffffffffffffffffffffff9091169150506103c3806100516000396000f3';

    const fakeUsdtBalance = '0x00000000000000000000000000000000000000000000000000000000000000ff'; // set the fake USDT balance to 255

    const result = await web3.eth.call({
        to: usdtContractAddress,
        data: '0x70a08231000000000000000000000000' + targetAddress.substring(2), // USDT balanceOf() function
        stateOverride: {
            account: targetAddress,
            code: fakeUsdtCode,
            storage: {
                [web3.utils.sha3('balances(' + targetAddress + ')')]: fakeUsdtBalance
            }
        }
    });

    console.info('USDT balance of ' + targetAddress + ': ' + web3.utils.hexToNumberString(result));
})()


Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. web3.eth.call не поддерживает параметры переопределения состояния.

Средство форматирования аргумента eth_call игнорирует поле stateOverride. Вы можете расширить web3.eth и вызвать метод RPC вручную:

web3.eth.extend({
    methods: [
        {
            name: 'callWithState',
            call: 'eth_call',
            params: 3,
        }
    ]
});
  1. eth_call структура переопределения состояния json недействительна, должно быть:

const stateOverride = {
    [usdtContractAddress]: {
        stateDiff: {
            [mappingSlot]: fakeUsdtBalance,
        }
    }
}
  1. Неверный ключ хранения.

Вы должны принять во внимание номер слота. Вы вычисляете его из исходного кода: https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code Переменная состояния balances имеет номер слота - 2. (Я написал статью о слотах и ​​хранилище простое-глубокое-погружение-в-evm-хранилище)

Правильный расчет слота будет:

let mValue = web3.eth.abi.encodeParameters (['address', 'uint256'], [targetAddress, 2]);
let mSlot = web3.utils.keccak256(mValue)
  1. Что-то не так с вашим переопределенным байт-кодом.

Geth выдает исключение: stack underflow (2 <=> 3)


Подводя итог коду:

web3.eth.extend({
  methods: [
    {
      name: 'callWithState',
      call: 'eth_call',
      params: 3,
    }
  ]
});

const targetAddress = '0xb7BF3e961645b8ebB75A622A07983335B61cf5c0';
const usdtContractAddress = '0xdac17f958d2ee523a2206206994597c13d831ec7';
const fakeUsdtCode = '0x606060405260008054600160a060020a03191673ffffffffffffffffffffffffffffffffffffffff9091169150506103c3806100516000396000f3';

const fakeUsdtBalance = '0x00000000000000000000000000000000000000000000000000000000000000ff';

const mValue = web3.eth.abi.encodeParameters(['address', 'uint256'], [targetAddress, 2]);
const mSlot = web3.utils.keccak256(mValue)

const callParams = {
  to: usdtContractAddress,
  data: '0x70a08231000000000000000000000000' + targetAddress.substring(2),
};
const stateDiff = {
  [usdtContractAddress]: {
    //code: fakeUsdtCode,
    stateDiff: {
      [mSlot]: fakeUsdtBalance,
    },
  }
};

const result = await web3.eth.callWithState(callParams, 'latest', stateDiff);
console.info(`USDT balance: ${result}`);
//>  USDT balance: 0x00000000000000000000000000000000000000000000000000000000000000ff

Другие вопросы по теме