«instance.at(addr) не является функцией» в консоли трюфеля (доступ к неперенесенным контрактам)

У меня есть настройка с одним контрактом, который является синглтоном и переносится, например, в тестовую сеть через консоль трюфеля. Этот контракт «создает» новые контракты, к которым я хочу получить доступ в консоли трюфеля. Поскольку новые контракты не переносятся через консоль, я хочу использовать ее instance.at(address)в команде, которую буду выполнять в трюфеле. Однако он не распознает экземпляр...

Контракты:
Singleton.sol → перенесены через truffle ManyOfMe.sol→ созданы через Singleton.sol

Ошибка:

TypeError: ManyOfMe.at не является функцией

Код: run.js выполняется через консоль трюфеля:exec ./run.js

const artifacts = require('./build/contracts/Singleton.json')
const ManyOfMe = require('./build/contracts/ManyOfMe.json')
const contract = require('truffle-contract')
const MyContract = contract(artifacts)
MyContract.setProvider(web3.currentProvider)

let Singleton
MyContract.deployed()
.then(async function(instance) {
  Singleton = instance

  let tokenAddress
  await Singleton.tokens(0).then(_ => {
    tokenAddress = _
  })
  return ManyOfMe.at(tokenAddress)
})
.then(function(instance) {
  instance.doSomething().then(_ => console.log(_))
})
.catch(function(error) {
  console.error(error)
})

PS: Если я просто наберу ManyOfMe в консоли трюфеля, я увижу функцию at, поэтому я не уверен, почему она не будет работать.

Ответы (1)

Когда вы запускаете скрипт с truffle exec, у вас уже будет контекст трюфеля (например artifacts), поэтому вам не нужно импортировать все вручную.

То, чего вы пытаетесь достичь, выглядит примерно так:

const Singleton = artifacts.require("Singleton");
const ManyOfMe = artifacts.require("ManyOfMe");

module.exports = function(done) {
    // code rewritten with async/await
    (async () => {
            var singleton = await Singleton.deployed();
            var manyOfMeAt0 = await ManyOfMe.at(await singleton.tokens(0));
            console.log(await manyOfMeAt0.doSomething());           

            done();
    })();
}

Более того, если вы можете использовать async/ await, то нет необходимости в then-цепочках. Это улучшает читаемость.

Отличный ответ! Я люблю читабельность! многое для меня прояснил. Последний вопрос: что за done()?
done — это сигнал для трюфеля о том, что вы закончили со своим сценарием. Поскольку здесь у вас есть asnyc-код, функция возвращается немедленно.
Спасибо чувак! Большое время! Вы оказали реальную помощь. Ты персик.
Пожалуйста. Не стесняйтесь проверять мои другие ответы. ;)