Solidity
Aufgabe 1
Erstellen Sie in der Remix IDE einen neuen Smart Contract. Nennen Sie ihn “DemoContract” und fügen Sie den folgenden Quellcode ein. Sie finden den Quellcode auch in der Datei contract_s2_03.sol.
pragma solidity 0.8.26;
contract DemoContract {
address public owner;
struct Receivers {
string name;
uint256 tokens;
}
mapping(address => Receivers) public users;
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
constructor(){
owner = msg.sender;
users[owner].tokens = 100; // Owner werden 100 Token gutgeschrieben
}
function double(uint _value) public pure returns (uint){
return _value*2;
}
function register(string memory _name) public{
users[msg.sender].name = _name;
}
function giveToken(address _receiver, uint256 _amount) onlyOwner public{
require(users[owner].tokens >= _amount);
users[owner].tokens -= _amount;
users[_receiver].tokens += _amount;
}
}
- Kompilieren Sie den Contract.
- Wenn das Kompilieren ohne Fehler funktioniert hat, können Sie den Smart Contract analog dem vorherigen Beispiel deployen.
- Sobald im Konsolenfenster zu sehen ist, dass der zweite Contract deployed wurde, wollen wir mit ihm interagieren.
- Dazu klappen wir den “DemoContract” in der mittleren Spalte der Remix IDE unter “Deployed Contracts” aus. Es sollten 6 Methoden zu sehen sein.
- Beachten Sie, dass die blauen Methoden so genannte “constant” Funktionen bzw. “view” / “pure” sind. Diese verändern der Zustand der Blockkette nicht und können einfach so ausgeführt werden, ohne eine Transaktion erstellen zu müssen.
- Die gelben Methoden hingegen verändern den Zustand der Blockkette und müssen entsprechend über Transaktionen (die Gebühren kosten) ausgeführt werden. Aus diesem Grund müssen Sie auch in MetaMask das Ausführen dieser Methoden bestätigen.
- Die roten Methoden sind Methoden, die eine Zahlung erwarten (payable).
Probieren Sie den Smart Contract aus.
Aufgabe 2
- Ändern Sie den Contract, sodass jeder Token vergeben kann (vorausgesetzt, er besitzt genügend davon).
- Ändern Sie den Contract, sodass jeder Token vom Owner gegen Ether kaufen kann (vorausgesetzt, der Owner besitzt noch ausreichend Token). 1 Token soll nach dem Deployment 2 Ether kosten.
- Fügen Sie eine Funktion ein, mit der nur der Owner den Preis ändern kann.
- Sollte der mitgeschickte Ether-Betrag nicht ausreichen oder der Owner nicht so viele Token übrig haben, soll eine Fehlermeldung mitgeschickt werden.
- Zeigen Sie an, wie hoch der Ether-Betrag ist, der auf dem Smart Contract liegt.
- Probieren Sie Ihren neuen Contract aus.
Hilfe
Damit eine Funktion Ether empfangen kann, muss sie mit payable gekennzeichnet sein.
function buyTokens(uint256 amount) payable public{
}
Den mitgeschickten Betrag erhalten Sie über msg.value. Die Angabe erfolgt in Wei!
Das Ether-Guthaben (in Wei) erhalten Sie mit address(this).balance.
Bei einer require-Anweisung kann als zweiter Parameter eine Fehlermeldung mitgeschickt werden: require(Bedingung, “Fehlermeldung”);
Bei einem Funktionsaufruf können Sie wie folgt Ether mitschicken: Tragen Sie im Feld „Value“ (siehe Screenshot) den gewünschten Betrag ein. Sie können daneben die Einheit wählen.
Die Lösung finden Sie in der Datei contract_s2_04.sol.
Lösung
// SPDX-License-Identifier: Unlicenced
pragma solidity 0.8.26;
contract DemoContract {
address public owner;
uint256 public price;
struct Receivers {
string name;
uint256 tokens;
}
mapping(address => Receivers) public users;
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
constructor(){
owner = msg.sender;
users[owner].tokens = 100; // Owner werden 100 Token gutgeschrieben
price = 2 ether;
}
function register(string memory _name) public{
users[msg.sender].name = _name;
}
function giveToken(address _receiver, uint256 _amount) public{
require(users[msg.sender].tokens >= _amount);
users[msg.sender].tokens -= _amount;
users[_receiver].tokens += _amount;
}
function buyTokens(uint256 _amount) public payable{
require(msg.value >= price * _amount, "Zu wenige Ether mitgeschickt.");
require(users[owner].tokens >= _amount, "Nicht mehr genug Token vorhanden");
users[owner].tokens -= _amount;
users[msg.sender].tokens += _amount;
}
function setPrice(uint256 _price) public onlyOwner{
price = _price;
// Angabe in wei
}
function getEhterAmount() public view returns(uint256){
return address(this).balance;
}
}