Ich teste den Crowdsale-Vertrag von https://ethereum.org/crowdsale auf einem lokalen Testrpc und kann nicht herausfinden, wie ich Geld dorthin senden kann. So wie ich es verstehe, erhält die anonyme Fallback-Funktion die an den Vertrag gesendeten Gelder. Die sendTransaction
Methode ist nicht direkt auf der Vertragsinstanz verfügbar, daher habe ich einige andere Optionen ausprobiert (und die Dokumentation gelesen und viel gegoogelt).
Irgendwelche Vorschläge?
Hier ist das Javascript:
const cl = console.log; cl; // avoid lint error
// const Web3 = require("web3");
if (typeof global.web3 !== 'undefined') {
global.web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
global.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
const web3 = global.web3;
web3.eth.defaultAccount = web3.eth.accounts[0];
var ifSuccessfulSendTo = web3.eth.accounts[1] /* var of type address here */ ;
var fundingGoalInEthers = 20 /* var of type uint256 here */ ;
var durationInMinutes = 10 /* var of type uint256 here */ ;
var etherCostOfEachToken = 0.2 /* var of type uint256 here */ ;
var addressOfTokenUsedAsReward = web3.eth.accounts[2] /* var of type address here */ ;
var browser_cs_sol_crowdsaleContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"safeWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"totalAmountRaised","type":"uint256"}],"name":"GoalReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]);
var browser_cs_sol_crowdsale = browser_cs_sol_crowdsaleContract.new(
ifSuccessfulSendTo,
fundingGoalInEthers,
durationInMinutes,
etherCostOfEachToken,
addressOfTokenUsedAsReward,
{
from: web3.eth.defaultAccount,
// from: web3.eth.accounts[3],
data: '0x60606040526000600760006101000a81548160ff0219169083151502179055506000600760016101000a81548160ff021916908315150217905550341561004557600080fd5b60405160a080610a4e833981016040528080519060200190919080519060200190919080519060200190919080519060200190919080519060200190919050505b846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550670de0b6b3a76400008402600181905550603c83024201600381905550670de0b6b3a7640000820260048190555080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505050505b6109038061014b6000396000f30060606040523615610097576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301cb3b201461027757806329dcb0cf1461028c57806338af3eed146102b55780636e66f6e91461030a57806370a082311461035f5780637a3a0e84146103ac5780637b3e5e7b146103d5578063a035b1fe146103fe578063fd6b7ef814610427575b5b6000600760019054906101000a900460ff161515156100b657600080fd5b34905080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555080600260008282540192505081905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb336004548481151561016257fe5b046040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15156101e757600080fd5b6102c65a03f115156101f857600080fd5b5050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826001604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a15b50005b341561028257600080fd5b61028a61043c565b005b341561029757600080fd5b61029f61051e565b6040518082815260200191505060405180910390f35b34156102c057600080fd5b6102c8610524565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561031557600080fd5b61031d610549565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561036a57600080fd5b610396600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061056f565b6040518082815260200191505060405180910390f35b34156103b757600080fd5b6103bf610587565b6040518082815260200191505060405180910390f35b34156103e057600080fd5b6103e861058d565b6040518082815260200191505060405180910390f35b341561040957600080fd5b610411610593565b6040518082815260200191505060405180910390f35b341561043257600080fd5b61043a610599565b005b6003544210151561051b576001546002541015156104fe576001600760006101000a81548160ff0219169083151502179055507fec3f991caf7857d61663fd1bba1739e04abd4781238508cde554bb849d790c856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600254604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b6001600760016101000a81548160ff0219169083151502179055505b5b5b565b60035481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60066020528060005260406000206000915090505481565b60015481565b60025481565b60045481565b6000600354421015156108d357600760009054906101000a900460ff16151561074a57600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000811115610749573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015610703577fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826000604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a1610748565b80600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b5b600760009054906101000a900460ff1680156107b257503373ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156108d1576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6002549081150290604051600060405180830381858888f19350505050156108b4577fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf66000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002546000604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a16108d0565b6000600760006101000a81548160ff0219169083151502179055505b5b5b5b5b505600a165627a7a7230582088450757203ab9947a54bcea1bbbf19594c4d831d252ff1c2df8a9999aa3ef350029',
gas: '4700000'
}, function (e, contract){
// console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
// cl('browser_cs_sol_crowdsale',browser_cs_sol_crowdsale)
const contract = global.contract = browser_cs_sol_crowdsale;
global.go = ()=>{
const params = {
from: web3.eth.defaultAccount
// from: web3.eth.accounts[5]
,to: contract.address
,value: web3.fromDecimal(20)
// ,value: 10
,gas: 1000000
};
cl('params',params);
// contract.beneficiary.sendTransaction( params, function(err, txHash) {
web3.eth.sendTransaction( params, function(err, txHash) {
if (err != null) {
cl("Error while sending transaction: " + err);
} else {
cl("Transaction sent, here's your txHash: " + txHash);
}
});
}; // go
module.exports = web3;
Was diesen Fehler erzeugt, wenn es go()
von der Konsole ausgeführt wird:
Error: VM Exception while processing transaction: invalid opcode
Hier ist der aktuelle Vertrag:
pragma solidity ^0.4.16;
// https://ethereum.org/crowdsale
interface token {
function transfer(address receiver, uint amount);
}
contract Crowdsale {
address public beneficiary;
uint public fundingGoal;
uint public amountRaised;
uint public deadline;
uint public price;
token public tokenReward;
mapping(address => uint256) public balanceOf;
bool fundingGoalReached = false;
bool crowdsaleClosed = false;
event GoalReached(address recipient, uint totalAmountRaised);
event FundTransfer(address backer, uint amount, bool isContribution);
/**
* Constrctor function
*
* Setup the owner
*/
function Crowdsale(
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
uint etherCostOfEachToken,
address addressOfTokenUsedAsReward
) {
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes;
price = etherCostOfEachToken * 1 ether;
tokenReward = token(addressOfTokenUsedAsReward);
}
/**
* Fallback function
*
* The function without name is the default function that is called whenever anyone sends funds to a contract
*/
function () payable {
require(!crowdsaleClosed);
uint amount = msg.value;
balanceOf[msg.sender] += amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price);
FundTransfer(msg.sender, amount, true);
}
modifier afterDeadline() { if (now >= deadline) _; }
/**
* Check if goal was reached
*
* Checks if the goal or time limit has been reached and ends the campaign
*/
function checkGoalReached() afterDeadline {
if (amountRaised >= fundingGoal){
fundingGoalReached = true;
GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
/**
* Withdraw the funds
*
* Checks to see if goal or time limit has been reached, and if so, and the funding goal was reached,
* sends the entire amount to the beneficiary. If goal was not reached, each contributor can withdraw
* the amount they contributed.
*/
function safeWithdrawal() afterDeadline {
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}
Eines der Probleme könnte darin bestehen, dass Sie tokenReward (die Adresse des Tokens, das Sie für die Verteilung verwenden) auf eines der eth-Konten festlegen, bei dem es sich um ein externes Konto (einen Benutzer) handelt. Der Crowdsale-Vertrag erfordert, dass Sie zuerst den Token-Vertrag bereitstellen, seine Adresse notieren und diese Adresse an den Crowdsale-Konstruktor weitergeben müssen.
Dies führt sicherlich dazu, dass es fehlschlägt, wenn Sie versuchen, die Funktion token.transfer() auf dieser Adresse auszuführen.
Ich empfehle Ihnen, all dies auf Remix anstelle von web3 auszuprobieren, damit Sie es einfach debuggen und die Funktionen jedes Vertrags aufrufen können, ohne weiteren Code schreiben zu müssen.
Jonas Ellehauge
Jonas Ellehauge
interface token
, ihre Adresse abrufen und diese Adresse an den Vertragskonstruktor übergeben sollte - als welcher Parameter? Und wie ermöglicht Remix die Übergabe von Werten an den Konstruktor?pabloruiz55
Jonas Ellehauge
Eis09
web3.eth.accounts[2]
) als Token-Adresse. Dies muss jedoch ein gültiger (ERC20) Token sein, der vor dem Crowdsale Smart Contract eingesetzt wird. Gehen Sie wahrscheinlich das Token-Beispiel auf der Website durch und gehen Sie dann erneut zum Crowdsale-Beispiel. Die Schnittstelletoken
wird verwendet, damit Sie dietransfer(...)
Funktion auf dem zuvor bereitgestellten ERC20-Token aufrufen können. Die ersten Argumente vontransfer(...)
sollten dann das Zielkonto sein, auf das Sie Token übertragen möchten.