Ich habe zwei Smart Contracts erstellt und beide werden im Ropsten Test Network bereitgestellt. Ich verwende MetaMask für Transaktionen.
ERC20-Token mit der folgenden Implementierung (bitte beachten Sie, dass ich meine in MetaMask verfügbaren Token sehen kann):
contract AppleToken is ERC20Interface, Owned, SafeMath {
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
function AppleToken() public {
symbol = "AppleToken";
name = "Apple Token";
decimals = 18;
_totalSupply = 100000000000000000000000000;
balances[0x2cBccb25319231B921fCf02Ec3bc213FcdFAeA15] = _totalSupply;
Transfer(address(0), 0x2cBccb25319231B921fCf02Ec3bc213FcdFAeA15, _totalSupply);
}
// ------------------------------------------------------------------------
// Total supply
// ------------------------------------------------------------------------
function totalSupply() public constant returns (uint) {
return _totalSupply - balances[address(0)];
}
// ------------------------------------------------------------------------
// Get the token balance for account tokenOwner
// ------------------------------------------------------------------------
function balanceOf(address tokenOwner) public constant returns (uint balance) {
return balances[tokenOwner];
}
// ------------------------------------------------------------------------
// Transfer the balance from token owner's account to to account
// - Owner's account must have sufficient balance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transfer(address to, uint tokens) public returns (bool success) {
balances[msg.sender] = safeSub(balances[msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
Transfer(msg.sender, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Token owner can approve for spender to transferFrom(...) tokens
// from the token owner's account
//
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// recommends that there are no checks for the approval double-spend attack
// as this should be implemented in user interfaces
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
Approval(msg.sender, spender, tokens);
return true;
}
// ------------------------------------------------------------------------
// Transfer tokens from the from account to the to account
//
// The calling account must already have sufficient tokens approve(...)-d
// for spending from the from account and
// - From account must have sufficient balance to transfer
// - Spender must have sufficient allowance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public returns (bool success) {
balances[from] = safeSub(balances[from], tokens);
allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
Transfer(from, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Returns the amount of tokens approved by the owner that can be
// transferred to the spender's account
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
return allowed[tokenOwner][spender];
}
// ------------------------------------------------------------------------
// Token owner can approve for spender to transferFrom(...) tokens
// from the token owner's account. The spender contract function
// receiveApproval(...) is then executed
// ------------------------------------------------------------------------
function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
Approval(msg.sender, spender, tokens);
ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
return true;
}
// ------------------------------------------------------------------------
// Don't accept ETH
// ------------------------------------------------------------------------
function () public payable {
revert();
}
// ------------------------------------------------------------------------
// Owner can transfer out any accidentally sent ERC20 tokens
// ------------------------------------------------------------------------
function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
return ERC20Interface(tokenAddress).transfer(owner, tokens);
}
}
Ein weiterer Smart Contract, der Ether empfängt und mit dem oben angegebenen Smart Contract interagieren sollte, um meine Token an den Absender von Ether zu übertragen.
Ich versuche zu implementieren, was in Punkt Nummer 2 erwähnt wird, aber wenn ich versuche, auf die „Transfer“-Funktion der ERC20-Token-Instanz zuzugreifen, erhalte ich einen Fehler, dass die Gasschätzung überschritten wird (ich habe versucht, das Gaslimit zu erhöhen, tut es nicht arbeiten). Wenn ich versuche, die Transaktion über MetaMask zu erzwingen, werden mir die Ausführungskosten mit 60001 Eth angezeigt, selbst wenn ich versuche, nur 1 Ether zu senden.
Hier ist die Implementierung meiner Funktion
IM JETZT BIN ICH DER SENDER VON ETHER UND ICH BIN DER EMPFÄNGER DER ERC20-TOKEN
function sendTokens () public payable returns (uint)
{
//tokenAddress is the address of the ERC20 token deployed on Ropsten
AppleToken appleToken;
appleToken = AppleToken(tokenAddress);
appleToken.transfer(msg.sender, 10);
return appleToken.balanceOf(msg.sender);
}
Ich sende im Moment zu Testzwecken fest codierte 10 Token. Beachten Sie, dass ich AppleToken mit import „browser/AppleToken.sol“ eingeschlossen habe;
Wenn ich NUR die Funktion appleToken.balanceOf ausführe, gibt sie nichts zurück. Zusammenfassend lässt sich sagen, dass die Funktion "Transfer" aufgrund der übermäßig berechneten Ausführungskosten problematisch ist und für "BalanceOf" nichts zurückgibt, nicht einmal eine 0.
Initiiere ich die Instanz von AppleToken korrekt? Oder mache ich noch etwas falsch?
Jede Hilfe wäre willkommen.
Danke schön.
AKTUALISIEREN
Öffentliche Kontoadresse auf Ropsten: 0x2cBccb25319231B921fCf02Ec3bc213FcdFAeA15
ERC20-Token-Adresse auf Ropsten: 0x580156edb25D3c3deD584F1075CcCC5dA4861883
Es folgt der gesamte Code des EquityInvestments-Vertrags:
Ich habe unnötige Dinge im Code entfernt, da ich diese Funktionen nicht aufrufe oder einige Variablen verwende, die für das Problem definiert sind, mit dem ich konfrontiert bin
pragma solidity ^0.4.16;
import "browser/AppleToken.sol";
contract EquityInvestments
{
AppleToken appleToken;
Group [] _Groups;
uint PriceEth = 1;
address tokenAddress = 0x580156edb25D3c3deD584F1075CcCC5dA4861883;
mapping (address => mapping(uint=>UserInvestment)) private _UserInvestments;
function EquityInvestments () public
{
_Groups.push(Group({
GroupID: 1,
GroupName: "Google",
TotalInvestment: 0,
GroupPriceDollars: 200,
GroupPriceEth: 1
}));
_Groups.push(Group({
GroupID: 2,
GroupName: "Tesla",
TotalInvestment: 0,
GroupPriceDollars: 200,
GroupPriceEth: 1
}));
_Groups.push(Group({
GroupID: 3,
GroupName: "Apple",
TotalInvestment: 0,
GroupPriceDollars: 200,
GroupPriceEth: 1
}));
}
struct Group
{
uint GroupID;
string GroupName;
uint TotalInvestment;
uint GroupPriceDollars;
uint GroupPriceEth;
}
function sendTokens () public payable returns (uint)
{
appleToken = AppleToken(tokenAddress);
// return appleToken.balanceOf(msg.sender);
// appleToken.approve(this, 10);
require(appleToken.transfer(msg.sender, 10));
return appleToken.balanceOf(msg.sender);
}
}
Ich kann nicht sehen, was mit dem Token-Vertrag nicht stimmt.
Was die zweite betrifft, sollten Sie Folgendes tun:
function sendTokens () public payable returns (uint)
{
AppleToken appleToken = AppleToken(tokenAddress);
require(appleToken.transfer(msg.sender, 10));
return appleToken.balanceOf(msg.sender);
}
tokenAddress
dies die richtige ist.require
Verwenden Sie beim Token-Transfer immer a ! Denken Sie nicht, dass es wie die transfer
Methode für funktioniert ether
, die Fehler behandelt und für Sie wirft.BEARBEITEN :
Ich habe die Verträge getestet und es funktioniert gut. Ich denke, Sie haben einfach vergessen, Token an den EquityInvestments
Vertrag zu senden, daher Token-Guthaben für den msg.sender
Aufenthalt bei 0
.
Um auf einen Kommentar von @elidrion näher einzugehen, die .transfer
Methode, die an Verträge angehängt ist, WIRD ETHER NOT TOKENS aus dem Nachrichtenvertrag an den Besitzer SENDEN.
Um beispielsweise Token aus einem Vertrag herauszuziehen, verwenden Sie nicht die von Solidity bereitgestellte globale Transfermethode, sondern tun Sie Folgendes:
function transferTokensOutOfTokenContract(uint tokens) public onlyOwner returns (bool success) {
require(tokens <= balances[address(this)]);
balances[address(this)] = balances[address(this)].sub(tokens);
balances[msg.sender] = balances[msg.sender].add(tokens);
emit Transfer(address(this), msg.sender, tokens);
return true;
}
Murad Hasan
Elisa Drion
Murad Hasan
Elisa Drion
Murad Hasan
Elisa Drion
transfer
funktioniert. Es "gibt" eine bestimmte Menge desmsg.sender
, der die Funktion aufruft, an eine andere Adresse. Wenn Ihr Vertrag keine Token enthält, kann er nichts an Personen senden , dieether
an ihn senden. In Ihrem Fall kann es nicht auf magische Weise neue Token prägen.Murad Hasan