Я понимаю, что вы можете отправить Эфириум на смарт-контракт, хотя, когда вы делаете это, sendTransaction
кажется, что вы не указываете функцию на смарт-контракте, когда делаете это. Я не совсем понимаю, чем это полезно. Однако то, что я не могу понять, как это сделать, это отправить эфириум функции, которая установлена как подлежащая оплате. Я использую ethers.js и могу создать контракт и вызывать функции, которые доступны для просмотра (только для чтения) без проблем, но я не могу понять, как отправить эфириум с транзакцией в конкретную функцию.
export const testContract = async (address, abi) => {
const wei = Utils.parseEther("0.1")
const url = "http://localhost:8545"
const provider = new Providers.JsonRpcProvider(url)
// Load the wallet to deploy the contract with
const privateKey =
"0x123"
const wallet = new Wallet(privateKey, provider)
var contract = new Contract(address, abi, wallet)
const price = await contract.retrievePrice()
console.log("price " + price) //logs the price set in the constructor when the contract was made (WORKS)
const testAddress = await contract.isUser(
"0x456"
)
console.log("testAddress ", testAddress) //checks if the given address is a user on the contract (WORKS)
const gasPrice = await provider.getGasPrice()
console.log("gas price: ", gasPrice.toString()) //returns the price of gas from the network (WORKS)
try {
const addToUsers = await contract.requestAccess({ //call function to request access, from the current wallet (REVERTS)
value: wei
})
console.log("result of sending transaction ", addToUsers)
} catch (error) {
console.log("error.... ", error) //fires as the contract reverted the payment
}
}
Любая помощь относительно того, почему звонок contract.requestAccess
возвращается на меня? Я не могу понять, как вызвать конкретную функцию и отправить эфир. Спасибо!
Ответ на комментарий
Итак, функция в контракте Solidity выглядит так:
function requestAccess() payable {
require(msg.value == price, "Incorrect sum sent to contract");
_addUser(msg.sender);
}
Я закомментировал требование, чтобы попробовать это, но все равно возвращается. _addUser из контракта, от которого наследуется мой, и выглядит так:
function _addUser(address account) internal {
users.add(account);
emit UserAdded(account);
}
users
есть Roles.Role private users;
и сидит в родительском контракте
contract Users {
using Roles for Roles.Role;
который импортирует из openzeppelin "openzeppelin-solidity/contracts/access/Roles.sol"
Вы можете заметить в комментариях, что я не смог понять, что у меня не работает, но я не фанат ответов «это работает, спасибо», которые не помогают другим. Итак, я привел рабочий пример для всех, кто ищет это. Просто нужно внести некоторые изменения, чтобы они соответствовали вашей ситуации, но должны быть относительно простыми. https://gist.github.com/amlwwalker/89bc2c5a2b631527bb7def922b4c8306
Цитата с https://github.com/ethers-io/ethers.js/issues/563
let overrides = {
// To convert Ether to Wei:
value: ethers.utils.parseEther("1.0") // ether in this case MUST be a string
// Or you can use Wei directly if you have that:
// value: someBigNumber
// value: 1234 // Note that using JavaScript numbers requires they are less than Number.MAX_SAFE_INTEGER
// value: "1234567890"
// value: "0x1234"
// Or, promises are also supported:
// value: provider.getBalance(addr)
};
// Pass in the overrides as the 3rd parameter to your 2-parameter function:
let tx = await exchangeContract.ethToTokenSwapOutput(tokens_bought, deadline, overrides);
Я не пробовал код, но каждый раз, когда вы хотите отправить эфир вместе с методом, вам нужно «переопределить» его.
Const overrides = {
value: ethers.utils.parseEther("1.0"), //sending one ether
gasLimit: 30000 //optional
}
//call your payable method using and use the override as a parameter
await contract.requestAccess( overrides )
В объект переопределения вы можете вставить несколько вещей, таких как gasLimit
overrides.from - msg.sender (или CALLER) для использования во время выполнения кода
overrides.value - msg.value (или CALLVALUE) для использования во время выполнения кода
overrides.gasPrice - цена за газ (теоретически); поскольку транзакции нет, комиссия не взимается, но EVM по-прежнему требует значения для сообщения в tx.gasprice (или GASPRICE); большинству разработчиков это не потребуется
overrides.gasLimit — количество газа (теоретически), позволяющее узлу использовать во время выполнения кода; поскольку транзакций нет, комиссия не взимается, но EVM по-прежнему обрабатывает показания газа, поэтому такие вызовы, как gasleft (или GAS), сообщают значимые значения.
overrides.blockTag — тег блока для имитации исполнения, который можно использовать для гипотетического исторического анализа; обратите внимание, что многие серверные части не поддерживают это или могут потребовать платные планы для доступа, поскольку требования к хранилищу и обработке базы данных узла намного выше.
Томас Вандерстратен
амлуокер
амлуокер
Томас Вандерстратен
амлуокер