Aus öffentlichen Paketdaten erstellte Orientierung.
flutter_web3 ist ein Flutter-Paket, das Ethereum-, Ether.js- und Wallet Connect-Funktionen für Webanwendungen kapselt. Es ermöglicht eine nahtlose Integration von Web3-Funktionen in Flutter-basierte dezentrale Anwendungen (DApps), insbesondere für die Webplattform. Das Paket vereinfacht die Interaktion mit Ethereum-Netzwerken, sodass Benutzer Wallets verbinden, Transaktionen signieren und Blockchain-Daten über eine dartfreundliche API verwalten können. Speziell für die DApp-Entwicklung konzipiert, vereinfacht es den Aufbau sicherer, interaktiver Blockchain-Erlebnisse im Web.
Anwendungsfälle
Ethereum-basierte DApps erstellen
Benutzer-Wallets über Wallet Connect verbinden
Unterschreiben und Senden von Ethereum-Transaktionen
Interaktion mit Smart Contracts im Web
Blockchain-Authentifizierung aktivieren
Benutzerkonten in DApps verwalten
Hauptmerkmale
Ethereum-Netzwerk-Integration
Wallet Connect-Unterstützung
Ether.js Wrapper für Web
Dart-native Web3-API
sichere Transaktionssignierung
Cross-Browser-Kompatibilität
Geeignet für
Flutter-Entwickler, die DApps erstellen
Web-fokussierte Blockchain-Anwendungen
Projekte, die eine Wallet-Verbindung erfordern
Teams, die Wallet Connect verwenden
Entwickler, die auf Ethereum-Netzwerke abzielen
frontend-lastige Blockchain-Oberflächen
Hinweise
Beschränkt auf Web-Plattform
Ethereum-kompatible Wallet erforderlich
Abhängig vom Web3-Anbieter des Browsers
Nicht geeignet für mobile oder Desktop-Anwendungen
This can be used to sign transaction and interact with smart contract, also query Blockchain data utils and a lot of helper function for developing dapps.
Prompt the connection to MetaMask or other provider.
// `Ethereum.isSupported` is the same as `ethereum != null`if (ethereum != null) {
try {
// Prompt user to connect to the provider, i.e. confirm the connection modalfinal accs = await ethereum!
.requestAccount(); // Get all accounts in node disposal
accs; // [foo,bar]
} onEthereumUserRejected {
print('User rejected the modal');
}
}
Subscribe to Ethereum events.
// Subscribe to `chainChanged` event
ethereum!.onChainChanged((chainId) {
chainId; // foo
});
// Subscribe to `accountsChanged` event.
ethereum!.onAccountsChanged((accounts) {
print(accounts); // ['0xbar']
});
// Subscribe to `message` event, need to convert JS message object to dart object.
ethereum!.on('message', (message) {
dartify(message); // baz
});
final web3provider = Web3Provider(ethereum!);
// orfinal web3provider = Web3Provider.fromEthereum(ethereum!);
// or
provider; // Default Web3Provider instance from default Ethereum provider
Connecting to Ethereum: RPC
final rpcProvider = JsonRpcProvider(); // Rpc Provider from default Rpc url, i.e. https://localhost:8545final rpcProvider = JsonRpcProvider('https://bsc-dataseed.binance.org/'); // Rpc Provider from specific Rpc url
Querying the Blockchain
// Look up the current block numberawait provider!.getBlockNumber(); // 9261427// Get the lastest block information that availableawait provider!.getLastestBlock(); // Block: 9261427 0x9e7900b8 mined at 2021-07-18T16:58:45.000 with diff 2// Get the specific account balanceawait provider!.getBalance('0xgarply'); // 315752957360231815// Get the transcation receipt of specific transaction hashawait provider!.getTransactionReceipt('0xwaldo'); // TransactionReceipt: 0x1612d8ba from 0x6886ec02 with 20 confirmations and 12 logs
final mnemonic =
"announce room limb pattern dry unit scale effort smooth jazz weasel alcohol";
final wallet = Wallet.fromMnemonic(mnemonic);
Or directly from private key.
final anotherWallet = Wallet(wallet.privateKey);
Then connect the wallet to specific provider.
// Connect wallet to networkfinal testnetProvider =
JsonRpcProvider('https://data-seed-prebsc-1-s2.binance.org:8545/');
final walletWithProvider = wallet.connect(testnetProvider);
After that, the wallet object can be used as normal signer object.
final tx = await walletWithProvider.sendTransaction(
TransactionRequest(
to: '0xbar',
value: BigInt.from(100),
),
); // Send 100 wei to `0xbar`
tx.hash; // 0xbash
Contract
Define ABI object, All ABI formats can be view here.
Note that you must be precise with the function argument and return types, this will yield different data types. For example, uint256 will yield BigNumber but uint16 will simply yield int. There might be error if you manually type this by hand.
final humanReadableAbi = [
"function balanceOf(address owner) view returns (uint256 balance)",
// Some examples with the struct type, we use the tuple keyword:// (note: the tuple keyword is optional, simply using additional// parentheses accomplishes the same thing)// struct Person {// string name;// uint16 age;// }"function addPerson(tuple(string name, uint16 age) person)", // Or "function addPerson((string name, uint16 age) person)"
];
final jsonAbi = '''[
{
"type": "function",
"name": "balanceOf",
"constant":true,
"stateMutability": "view",
"payable":false, "inputs": [
{ "type": "address", "name": "owner"}
],
"outputs": [
{ "type": "uint256"}
]
}
]''';
// Contruct Interface object out of `humanReadableAbi` or `jsonAbi`final humanInterface = Interface(humanReadableAbi);
final jsonInterface = Interface(jsonAbi);
// These two abi interface can be exchanged
humanInterface.format(FormatTypes.minimal); // [function balanceOf(address) view returns (uint256)]
humanInterface.format(FormatTypes.minimal)[0] == jsonInterface.format(FormatTypes.minimal)[0]; // true
Initialize Contract object.
final abi = [
// Some details about the token"function name() view returns (string)",
"function symbol() view returns (string)",
// Get the account balance"function balanceOf(address) view returns (uint)",
// Send some of your tokens to someone else"function transfer(address to, uint amount)",
// An event triggered whenever anyone transfers to someone else"event Transfer(address indexed from, address indexed to, uint amount)"
];
final busdAddress = '0xe9e7cea3dedca5984780bafc599bd69add087d56';
// Use `Provider` for Read-only contract, i.e. Can't call state-changing methodfinal busd = Contract(
busdAddress,
abi,
provider!,
);
// Use `Signer` for Read-write contract// Notice that ABI can be exchangeablefinal anotherBusd = Contract(
busdAddress,
Interface(abi),
provider!.getSigner(),
);
// Or `busd.connect(provider!.getSigner());`
final abi = "function throw() payable";
final contract = Contract('0xrandomContract', abi, provider!);
// Send 100 wei of ether alongfinal tx = await contract.send(
'throw',
[],
TransactionOverride(value: BigInt.from(100)),
);
tx.hash; // 0xfoo
Listening to Events.
// Receive an event when ANY transfer occurs
busd.on('Transfer', (from, to, amount, event) {
from; // 0x0648ff5de80Adf54aAc07EcE2490f50a418Dde23
to; // 0x12c64E61440582793EF4964A36d98020d83490a3
amount; // 1015026418461703883891Event.fromJS(event); // Event: Transfer Transfer(address,address,uint256) with args [0x0648ff5de80Adf54aAc07EcE2490f50a418Dde23, 0x12c64E61440582793EF4964A36d98020d83490a3, 1015026418461703883891]
});
// A filter for when a specific address receives tokensfinal myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
final filter = busd.getFilter('Transfer', [null, myAddress]);
// {// address: '0xe9e7cea3dedca5984780bafc599bd69add087d56',// topics: [// '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',// null,// '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72'// ]// }
busd.on(filter, (from, to, amount, event) {
// ...
});
Query Historic Events
final filter = busd.getFilter('Transfer');
// Query past event in last 100 blocks.final events = await busd.queryFilter(filter, -100);
events.first; // Event: Transfer Transfer(address,address,uint256) with args [0x209F2A37Ccb5672794329cB311406A995de9347c, 0x928bE3DEB1f8B9e4A24a5744bD313E726462961D, 150000000000000000000]
Alternatively for ERC20 Contract, we can use ContractERC20 class.