#solidity #truffle
#солидность #truffle
Вопрос:
Итак, я пытаюсь протестировать платную функцию в следующем смарт-контракте, используя truffle framework:
contract FundMe {
using SafeMathChainlink for uint256;
mapping(address => uint256) public addressToAmountFunded;
address[] public funders;
address public owner;
AggregatorV3Interface public priceFeed;
constructor(address _priceFeed) public {
priceFeed = AggregatorV3Interface(_priceFeed);
owner = msg.sender;
}
function fund() public payable {
uint256 mimimumUSD = 50 * 10**18;
require(
getConversionRate(msg.value) >= mimimumUSD,
"You need to spend more ETH!"
);
addressToAmountFunded[msg.sender] = msg.value;
funders.push(msg.sender);
}
Я специально хочу протестировать функцию оплаты, и я видел несколько вещей в Интернете, где люди создают другие контракты с начальными балансами, а затем отправляют свой контракт на тестирование в eth. Но я просто хотел бы захватить локальный кошелек ganache и отправить немного eth в контракт, а затем проверить это, если бы кто-нибудь мог показать мне какой-нибудь тестовый код javascript, чтобы я мог понять это, это было бы очень ценно!
Ответ №1:
Чтобы контракт мог получать ETH (или любой собственный токен — BNB в Binance Smart Chain, TRX в сети Tron, …) без вызова какой-либо функции, вам необходимо определить хотя бы одну из этих функций receive()
(docs) или fallback()
(docs).
contract FundMe {
// intentionally missing the `function` keyword
receive() external payable {
// can be empty
}
// ... rest of your code
}
Затем вы можете отправить обычную транзакцию на адрес контракта в truffle (docs):
const instance = await MyContract.at(contractAddress);
await instance.send(web3.toWei(1, "ether"));
Обратите внимание, что, поскольку receive()
и fallback()
не являются обычными функциями, вы не можете вызывать их с помощью автоматически созданных методов truffle: myContract.functionName()
Если вы хотите выполнить платную функцию, отправив ей ETH, вы можете использовать transaction params
(docs) . Это всегда последний аргумент после всех обычных аргументов функции.
const instance = await MyContract.at(contractAddress);
await instance.fund({
value: web3.toWei(1, "ether")
});
Примечание: если fund()
бы функция имела 1 аргумент (скажем, a bool
), transaction params
он был бы 2-м:
await instance.fund(true, {
value: web3.toWei(1, "ether")
});
Комментарии:
1. Итак, если бы я хотел сделать что-то вроде обновления данной переменной или переадресации ее в другую функцию, это произошло бы в рамках этой функции приема?
2. @SonnyVesali Я также обновил свой ответ в этом случае. Сначала я понял ваш вопрос только как отправку ETH в контракт без выполнения какой-либо функции.
3. Это единственный способ заплатить ETH контракту сейчас? Ранее
payable
она могла быть отмечена для любой функции, но я получал необъяснимую ошибку возврата с последней версией Solidity до изменения моейpayable
функции наreceive() external payable
.4. @Neo Вы можете использовать
payable
модификатор для любой функции. Полученный вами возврат, похоже, не связан с функциейpayable
.