Ich möchte drei Token-Verträge A, B und C schreiben, die miteinander interagieren können. A ist der Haupttoken, B und C sind die Untertokens. Ein Käufer kann den Haupt-Token (Token A) kaufen und damit die Unter-Token (Token B und Token C) kaufen. Nach dem Kauf der Sub-Token sollte das Guthaben des Käufers des Haupt-Tokens sinken und das Guthaben der Sub-Tokens steigen. Wie soll ich diese drei Verträge gestalten? Ich ändere jetzt den ERC20-Standard-Token, weiß aber nicht, wie ich die Funktion transferFrom im ERC20 so gestalten soll, dass sie die oben genannten Bedingungen erfüllt?
Dies ist so einfach wie das Einfügen von Methoden, die es den übergeordneten Verträgen ermöglichen, Funktionen im untergeordneten Vertrag auszuführen, die Aktionen ausführen.
Sie könnten eine Funktion im übergeordneten Element haben, die es ihm bei Ausführung durch einen Token-Inhaber ermöglicht, Gelder auf einen untergeordneten Vertrag zu überweisen und anschließend im untergeordneten Vertrag das übergeordnete Element erneut anzurufen.
Das folgende Beispiel implementiert einen Vertrag, der zwei Unterverträge erstellt, und Übertragungsfunktionen, die es ermöglichen, die Gelder zwischen dem Elternteil und den Kindern hin und her zu transferieren.
Es wird dem Ersteller zunächst 1000 Main-Token geben, dann könnte der Besitzer zum Beispiel anrufen Main.buyB(10)
. Der Besitzer hätte dann 990 Main und 10 B. Der Besitzer könnte dann anschließend anrufen B.sell(5)
und 995 Main und 5 B haben.
pragma solidity ^0.4.21;
/// @title Tracks ownershipt of the descendant token.
contract Owned {
address owner;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
}
/// @title Should be a fully functioning token, only a stub is provided below,
/// for demonstration purposes.
contract Token is Owned {
mapping(address => uint) balances;
/// @notice ERC20 - Returns the balance of the requested address.
/// @param _to The address to return the balance for.
/// @return The token balance of `_to`.
function balanceOf(address _to) external view returns (uint) {
return balances[_to];
}
// Contains all the other standard ERC20 token junk.
}
/// @title Is the main contract which can buy B or C tokens.
contract Main is Owned, Token {
// The first "B" sub-token.
Sub public b_token;
// The second "C" sub-token.
Sub public c_token;
/// @notice Creates a new Main token, then creates 2 sub-tokens and saves them.
function Main() public {
// Grant the creator 1000 Main tokens.
balances[msg.sender] = 1000;
// Create 2 new sub contracts and save them as b_token and c_token.
b_token = new Sub();
c_token = new Sub();
}
/// @notice Buys a given number of B tokens using the balance of the Main token.
/// @param _value The amount of B to buy with Main.
function buyB(uint _value) external {
require(balances[msg.sender] > _value);
balances[msg.sender] -= _value;
b_token._give(msg.sender, _value);
}
/// @notice Buys a given number of C tokens using the balance of the Main token.
/// @param _value The amount of C to buy with Main.
function buyC(uint _value) external {
require(balances[msg.sender] > _value);
balances[msg.sender] -= _value;
c_token._give(msg.sender, _value);
}
/// @notice Gives `_value` worth of Main tokens to `_to`.
/// @dev Only callable by B or C children contracts.
/// @param _to The address to give Main to.
/// @param _value The amount of Main to give to `_to`.
function _give(address _to, uint _value) external {
require(msg.sender == address(b_token) || msg.sender == address(c_token));
balances[_to] += _value;
require(balances[_to] >= _value);
}
}
/// @title A sub-token of `Main`, purchasable using Main token, and sellable for
/// Main token.
contract Sub is Token {
/// @notice Creates a new Sub token and assigns the creator (`Main`) as the owner.
function Sub() public {
owner = msg.sender;
}
/// @notice Gives `_value` worth of this tokens to `_to`.
/// @dev Only callable by parent Main contract.
/// @param _to The address to give this token to.
/// @param _value The amount of this token to give to `_to`.
function _give(address _to, uint _value) external onlyOwner {
balances[_to] += _value;
require(balances[_to] >= _value);
}
/// @notice Sells a given value of this token and gives back parent `Main` token.
/// @param _value The amount of this token to sell.
function sell(uint _value) external {
require(balances[msg.sender] >= _value);
balances[msg.sender] -= _value;
Main(owner)._give(msg.sender, _value);
}
}
Eine Möglichkeit besteht darin, Vertrag A als einfachen ERC20-Token zu behalten, dem nichts hinzugefügt wird. Wenn also jemand A überträgt, balances
wird das Array geändert.
Die Verträge B und C wären etwas spezielle ERC20-Token. Beginnen Sie mit ERC20, aber fügen Sie einige Kauf- (und Verkauf-) Methoden hinzu, die das Guthaben in Vertrag A ändern, um ihre A-Token zu verringern und das Guthaben in B/C-Vertrag zu erhöhen. Ich glaube eigentlich nicht, dass es noch viele andere Kuriositäten geben würde - sonst könnten B und C wie normale ERC20 verwendet werden.
supakaity
2341047123413331
magisch007
Achala Dissanayake
Henk