AW Nomad|Public Goods Builder

How to build a social component
Ame Network has been deployed on multiple testnets. This tutorial will guide you to quickly build a social component.Component StructureYou can copy the Component template directly, or implement a component based on IComponent.Component introduction: The methodRequests and methodResponses are used to define the request parameter type and response data type of Method. Type is a data type Library, which contains all data types of solidity.mapping (string=>Types.Type[]) methodRequests; mapping (...

Build your first fully on-chain game
The core principle of a fully on-chain game is to use contracts to implement game data and game logic. So how to implement the simplest a fully on-chain game? This tutorial does not use any development framework or game engine. You only need to know some of the simplest solidity codes.Entity Component SystemECS is a design pattern that improves code reusability by separating data from behavior. It is often used in game development. A minimal ECS consists of:Entity: a unique identifier.Compone...

Subscribe to Rickey

How to build a social component
Ame Network has been deployed on multiple testnets. This tutorial will guide you to quickly build a social component.Component StructureYou can copy the Component template directly, or implement a component based on IComponent.Component introduction: The methodRequests and methodResponses are used to define the request parameter type and response data type of Method. Type is a data type Library, which contains all data types of solidity.mapping (string=>Types.Type[]) methodRequests; mapping (...

Build your first fully on-chain game
The core principle of a fully on-chain game is to use contracts to implement game data and game logic. So how to implement the simplest a fully on-chain game? This tutorial does not use any development framework or game engine. You only need to know some of the simplest solidity codes.Entity Component SystemECS is a design pattern that improves code reusability by separating data from behavior. It is often used in game development. A minimal ECS consists of:Entity: a unique identifier.Compone...
Share Dialog
Share Dialog


<100 subscribers
<100 subscribers
It is a temporary wallet. You only need to deposit a small amount of funds into the burner wallet. It is used for some high-frequency and small-amount transactions. Because its private key is stored in the browser, it is less secure. If you accidentally clear the cache, the private key may be lost.
Burner Wallet was first proposed by Austin Griffith, and Dark Forest v0.4 started adopting it. This design has continued until now. In the Skystrife game, it is named session wallet.


When we interact with the contract in the browser, we need to wake up the metamask, and then click the send button. Each time we click send, the private key signs the transaction and sends it. However, in a full-chain game, we need to interact with the contract many times. You need to click the metamask send button frequently, which makes players' fingers very painful.
If you use Burner Wallet, every time you perform an operation in the game, you don't need to click send to confirm. Burner Wallet will directly sign and send the transaction. This makes your gaming experience better.
First, generate an EVM-compatible wallet. There are many ways. We import an eth-crypto package, which can help us quickly generate a wallet.
{
privateKey:"0x3d29900e7c9be8ad87f840f869695e0b56ed02abec57f36f0cc354ea48b326aa",
publicKey:"48dee7634338659e31a3cf1612e9b2694c6e0fd8d05d3bd16acbe47f34ad1ed49f868633a4d642713aaeb0b0ff2b5368d77ce945d474f88eba31e3b621d8cd79",
address:"0x72fAe99E0aaC8847bC07b05fA509242c9F787a6a"
}
Save wallet in local storage
const burnerWallet = EthCrypto.createIdentity();
localStorage.setItem("burnerWallet", JSON.stringify(burnerWallet));

Use web3 to connect to network rpc directly instead of using window.ethereum
const web3 = new Web3("http://127.0.0.1:7545");
var contract = new web3.eth.Contract(
MoveABI,
"0x6DA6d3698Ba0189C94D1B7e470a2C61F47660002"
);
Get the burner wallet from local storage and import it
const burnerWallet = JSON.parse(localStorage.getItem("burnerWallet"));
web3.eth.accounts.wallet.add(burnerWallet.privateKey);
Perform in-game actions, before doing this, don’t forget to transfer some gas fees to your burner wallet.
const gasPrice = await web3.eth.getGasPrice();
const gas = await contract.methods
.move(randomPosition, randomPosition)
.estimateGas({ from: burnerWallet.address });
const transactionResult = await contract.methods
.move(randomPosition, randomPosition)
.send({ from: burnerWallet.address, gasPrice: gasPrice, gas: gas });
Wrap up
import React, { useState, useEffect } from "react";
import EthCrypto from "eth-crypto";
import Web3 from "web3";
import MoveABI from "./move.json";
function BurnerWallet(props) {
const generateBurnWallet = () => {
const burnerWallet = EthCrypto.createIdentity();
console.log("burnerWallet",burnerWallet);
localStorage.setItem("burnerWallet", JSON.stringify(burnerWallet));
};
const move = async () => {
const web3 = new Web3("http://127.0.0.1:7545");
var contract = new web3.eth.Contract(
MoveABI,
"0x6DA6d3698Ba0189C94D1B7e470a2C61F47660002"
);
const burnerWallet = JSON.parse(localStorage.getItem("burnerWallet"));
web3.eth.accounts.wallet.add(burnerWallet.privateKey);
const randomPosition = Math.floor(Math.random() * 101);
const gasPrice = await web3.eth.getGasPrice();
const gas = await contract.methods
.move(randomPosition, randomPosition)
.estimateGas({ from: burnerWallet.address });
const transactionResult = await contract.methods
.move(randomPosition, randomPosition)
.send({ from: burnerWallet.address, gasPrice: gasPrice, gas: gas });
console.log("transactionResult", transactionResult);
const position = await contract.methods
.getPosition(burnerWallet.address)
.call();
console.log("position", position);
};
return (
<div>
<button onClick={generateBurnWallet}>Generate Burner Wallet</button>
<button onClick={move}>Move</button>
</div>
);
}
export default BurnerWallet;
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;
contract Move{
struct Position{
uint x;
uint y;
}
mapping (address=>Position) Positions;
function move(uint _x,uint _y)public{
Positions[msg.sender]=Position(_x,_y);
}
function getPosition(address _addr)public view returns(uint,uint){
return (Positions[_addr].x,Positions[_addr].y);
}
}
In order to prevent players from losing their burner wallet, each time a player creates a burner wallet, it is downloaded locally. This adds a backup.
const writeToFile = (burnerWallet) => {
const fileData = JSON.stringify(burnerWallet);
const blob = new Blob([fileData], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'BurnWallet.json';
link.href = url;
link.click();
};
In order to increase the security of the local storage wallet, you can add AES encryption, set a password for your burner wallet, and then save it in local storage. Each time the player opens the page to play the game, enter the password to decrypt it.
import CryptoJS from "crypto-js";
const aesEncrypt = CryptoJS.AES.encrypt(privateKey, "password").toString();
const aesDecrypt=CryptoJS.AES.decrypt(aesEncrypt,"password").toString(CryptoJS.enc.Utf8);
If you have any questions or interesting ideas about Burner Wallet, you can contact me on twitter.
It is a temporary wallet. You only need to deposit a small amount of funds into the burner wallet. It is used for some high-frequency and small-amount transactions. Because its private key is stored in the browser, it is less secure. If you accidentally clear the cache, the private key may be lost.
Burner Wallet was first proposed by Austin Griffith, and Dark Forest v0.4 started adopting it. This design has continued until now. In the Skystrife game, it is named session wallet.


When we interact with the contract in the browser, we need to wake up the metamask, and then click the send button. Each time we click send, the private key signs the transaction and sends it. However, in a full-chain game, we need to interact with the contract many times. You need to click the metamask send button frequently, which makes players' fingers very painful.
If you use Burner Wallet, every time you perform an operation in the game, you don't need to click send to confirm. Burner Wallet will directly sign and send the transaction. This makes your gaming experience better.
First, generate an EVM-compatible wallet. There are many ways. We import an eth-crypto package, which can help us quickly generate a wallet.
{
privateKey:"0x3d29900e7c9be8ad87f840f869695e0b56ed02abec57f36f0cc354ea48b326aa",
publicKey:"48dee7634338659e31a3cf1612e9b2694c6e0fd8d05d3bd16acbe47f34ad1ed49f868633a4d642713aaeb0b0ff2b5368d77ce945d474f88eba31e3b621d8cd79",
address:"0x72fAe99E0aaC8847bC07b05fA509242c9F787a6a"
}
Save wallet in local storage
const burnerWallet = EthCrypto.createIdentity();
localStorage.setItem("burnerWallet", JSON.stringify(burnerWallet));

Use web3 to connect to network rpc directly instead of using window.ethereum
const web3 = new Web3("http://127.0.0.1:7545");
var contract = new web3.eth.Contract(
MoveABI,
"0x6DA6d3698Ba0189C94D1B7e470a2C61F47660002"
);
Get the burner wallet from local storage and import it
const burnerWallet = JSON.parse(localStorage.getItem("burnerWallet"));
web3.eth.accounts.wallet.add(burnerWallet.privateKey);
Perform in-game actions, before doing this, don’t forget to transfer some gas fees to your burner wallet.
const gasPrice = await web3.eth.getGasPrice();
const gas = await contract.methods
.move(randomPosition, randomPosition)
.estimateGas({ from: burnerWallet.address });
const transactionResult = await contract.methods
.move(randomPosition, randomPosition)
.send({ from: burnerWallet.address, gasPrice: gasPrice, gas: gas });
Wrap up
import React, { useState, useEffect } from "react";
import EthCrypto from "eth-crypto";
import Web3 from "web3";
import MoveABI from "./move.json";
function BurnerWallet(props) {
const generateBurnWallet = () => {
const burnerWallet = EthCrypto.createIdentity();
console.log("burnerWallet",burnerWallet);
localStorage.setItem("burnerWallet", JSON.stringify(burnerWallet));
};
const move = async () => {
const web3 = new Web3("http://127.0.0.1:7545");
var contract = new web3.eth.Contract(
MoveABI,
"0x6DA6d3698Ba0189C94D1B7e470a2C61F47660002"
);
const burnerWallet = JSON.parse(localStorage.getItem("burnerWallet"));
web3.eth.accounts.wallet.add(burnerWallet.privateKey);
const randomPosition = Math.floor(Math.random() * 101);
const gasPrice = await web3.eth.getGasPrice();
const gas = await contract.methods
.move(randomPosition, randomPosition)
.estimateGas({ from: burnerWallet.address });
const transactionResult = await contract.methods
.move(randomPosition, randomPosition)
.send({ from: burnerWallet.address, gasPrice: gasPrice, gas: gas });
console.log("transactionResult", transactionResult);
const position = await contract.methods
.getPosition(burnerWallet.address)
.call();
console.log("position", position);
};
return (
<div>
<button onClick={generateBurnWallet}>Generate Burner Wallet</button>
<button onClick={move}>Move</button>
</div>
);
}
export default BurnerWallet;
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;
contract Move{
struct Position{
uint x;
uint y;
}
mapping (address=>Position) Positions;
function move(uint _x,uint _y)public{
Positions[msg.sender]=Position(_x,_y);
}
function getPosition(address _addr)public view returns(uint,uint){
return (Positions[_addr].x,Positions[_addr].y);
}
}
In order to prevent players from losing their burner wallet, each time a player creates a burner wallet, it is downloaded locally. This adds a backup.
const writeToFile = (burnerWallet) => {
const fileData = JSON.stringify(burnerWallet);
const blob = new Blob([fileData], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'BurnWallet.json';
link.href = url;
link.click();
};
In order to increase the security of the local storage wallet, you can add AES encryption, set a password for your burner wallet, and then save it in local storage. Each time the player opens the page to play the game, enter the password to decrypt it.
import CryptoJS from "crypto-js";
const aesEncrypt = CryptoJS.AES.encrypt(privateKey, "password").toString();
const aesDecrypt=CryptoJS.AES.decrypt(aesEncrypt,"password").toString(CryptoJS.enc.Utf8);
If you have any questions or interesting ideas about Burner Wallet, you can contact me on twitter.
No activity yet