1652485560
Ethrpc
Golang client for ethereum JSON RPC API.
Usage:
package main
import (
"fmt"
"log"
"github.com/onrik/ethrpc"
)
func main() {
client := ethrpc.New("http://127.0.0.1:8545")
version, err := client.Web3ClientVersion()
if err != nil {
log.Fatal(err)
}
fmt.Println(version)
// Send 1 eth
txid, err := client.EthSendTransaction(ethrpc.T{
From: "0x6247cf0412c6462da2a51d05139e2a3c6c630f0a",
To: "0xcfa202c4268749fbb5136f2b68f7402984ed444b",
Value: ethrpc.Eth1(),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(txid)
}
Author: Onrik
Source Code: https://github.com/onrik/ethrpc
License: MIT license
1652415199
This course will teach you everything you need to create and deploy your own dApps - the backbone of Web3.
Filip will teach you the end-to-end dApp development process for Ethereum. You'll get to build and test your own dApps and Smart Contracts too! After this course, you'll have practical knowledge of Web3.js, MetaMask, Truffle, and Ganache, and your very own dApp.
Filip has a background in Computer Science within the Swedish Banking sector and was an early adopter of Bitcoin. He is the "other half" behind Ivan on Tech Academy and a true programming mastermind. Previously, he was the CEO of Stockholm Blockchain Group and has worked as a Blockchain Consultant with clients from all over the world. During his free time he enjoys reading non-fiction books and long walks.
Ivan runs Ivan on Tech - one of the most successful and trusted blockchain channels on Youtube and is also an international blockchain speaker and educator. Millions of people all around the world have listened, learned and been inspired by Ivan. Now he has created a course for his followers and subscribers, so that they can get the same knowledge as the big corporations.
#web3 #nft #blockchain #dapp #nonfungibletoken #ethereum
1652290500
In this tutorial, We'll show you How to Create Blockchain Dapp with Ethereum and VueJS.
First let's create the project folder called ethereum-vuejs-dapp
, then open the terminal in the folder just created and run the following command:
$ truffle init
This command initializes the truffle project and creates the following items:
Let's add the details of our blockchain network to the file truffle.js
. So first start Ganache and, once it runs, check the host and the port as shown below.
Now paste the following code in truffle.js
:
module.exports = {
networks: {
ganache: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
}
}
};
IMPORTANT: make sure that the host and the port of the code pasted in truffle.js
match with the settings displayed in Ganache.
As described in the introduction, the main features of our dApp are:
The following information of a user's profile is going to be stored in the blockchain:
What we need is to store the list of the users and associate each user with an account address (or wallet address).
The smart contract must provide a set of functions that:
Below is the code of the smart contract (you can find it on GitHub as well).
pragma solidity ^0.5.0;
contract Users {
// data structure that stores a user
struct User {
string name;
bytes32 status;
address walletAddress;
uint createdAt;
uint updatedAt;
}
// it maps the user's wallet address with the user ID
mapping (address => uint) public usersIds;
// Array of User that holds the list of users and their details
User[] public users;
// event fired when an user is registered
event newUserRegistered(uint id);
// event fired when the user updates his status or name
event userUpdateEvent(uint id);
// Modifier: check if the caller of the smart contract is registered
modifier checkSenderIsRegistered {
require(isRegistered());
_;
}
/**
* Constructor function
*/
constructor() public
{
// NOTE: the first user MUST be emtpy: if you are trying to access to an element
// of the usersIds mapping that does not exist (like usersIds[0x12345]) you will
// receive 0, that's why in the first position (with index 0) must be initialized
addUser(address(0x0), "", "");
// Some dummy data
addUser(address(0x333333333333), "Leo Brown", "Available");
addUser(address(0x111111111111), "John Doe", "Very happy");
addUser(address(0x222222222222), "Mary Smith", "Not in the mood today");
}
/**
* Function to register a new user.
*
* @param _userName The displaying name
* @param _status The status of the user
*/
function registerUser(string memory _userName, bytes32 _status) public
returns(uint)
{
return addUser(msg.sender, _userName, _status);
}
/**
* Add a new user. This function must be private because an user
* cannot insert another user on behalf of someone else.
*
* @param _wAddr Address wallet of the user
* @param _userName Displaying name of the user
* @param _status Status of the user
*/
function addUser(address _wAddr, string memory _userName, bytes32 _status) private
returns(uint)
{
// checking if the user is already registered
uint userId = usersIds[_wAddr];
require (userId == 0);
// associating the user wallet address with the new ID
usersIds[_wAddr] = users.length;
uint newUserId = users.length++;
// storing the new user details
users[newUserId] = User({
name: _userName,
status: _status,
walletAddress: _wAddr,
createdAt: now,
updatedAt: now
});
// emitting the event that a new user has been registered
emit newUserRegistered(newUserId);
return newUserId;
}
/**
* Update the user profile of the caller of this method.
* Note: the user can modify only his own profile.
*
* @param _newUserName The new user's displaying name
* @param _newStatus The new user's status
*/
function updateUser(string memory _newUserName, bytes32 _newStatus) checkSenderIsRegistered public
returns(uint)
{
// An user can modify only his own profile.
uint userId = usersIds[msg.sender];
User storage user = users[userId];
user.name = _newUserName;
user.status = _newStatus;
user.updatedAt = now;
emit userUpdateEvent(userId);
return userId;
}
/**
* Get the user's profile information.
*
* @param _id The ID of the user stored on the blockchain.
*/
function getUserById(uint _id) public view
returns(
uint,
string memory,
bytes32,
address,
uint,
uint
) {
// checking if the ID is valid
require( (_id > 0) || (_id <= users.length) );
User memory i = users[_id];
return (
_id,
i.name,
i.status,
i.walletAddress,
i.createdAt,
i.updatedAt
);
}
/**
* Return the profile information of the caller.
*/
function getOwnProfile() checkSenderIsRegistered public view
returns(
uint,
string memory,
bytes32,
address,
uint,
uint
) {
uint id = usersIds[msg.sender];
return getUserById(id);
}
/**
* Check if the user that is calling the smart contract is registered.
*/
function isRegistered() public view returns (bool)
{
return (usersIds[msg.sender] > 0);
}
/**
* Return the number of total registered users.
*/
function totalUsers() public view returns (uint)
{
// NOTE: the total registered user is length-1 because the user with
// index 0 is empty check the contructor: addUser(address(0x0), "", "");
return users.length - 1;
}
}
It's time to deploy the smart contract to the blockchain! Make sure that your blockchain is running and the file truffle.js
is properly set as explained before.
Go to the folder migration and create a file called 2_migrate_users.js
.
The migration filename has a number as prefix and a description as suffix. The numbered prefix is required in order to record whether the migration ran successfully and the suffix just describes what the file is about.
Copy and paste the following code inside the file 2_migrate_users.js
:
var Users = artifacts.require("./Users.sol");
module.exports = function(deployer) {
deployer.deploy(Users);
};
Now let's open the terminal in the project folder ethereum-vuejs-dapp
and run the command:
$ truffle console ––network ganache
Once the truffle console is running, type the following command:
>> migrate ––reset ––compile-all
This command compiles all smart contracts and deploys the smart contracts to the blockchain.
If everything went fine, on the console you should see a message as follows:
Compiling .\contracts\Migrations.sol...
Compiling .\contracts\Users.sol...
Writing artifacts to .\build\contracts
Using network 'ganache'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0x18edd24941e9b7edfae4966af544d5413e31622da90cecae2d3153635a7ffba2
Migrations: 0xcac26201ab3b38d2f0f9b56f81a8897dfe036da6
Saving successful migration to network...
... 0x125c70f37e143b13acb4827dda16e8571758402db81c08a3a2ae27573910105f
Saving artifacts...
Running migration: 2_migrate_users.js
Replacing Users...
... 0x043c2cf363da321b8a1ec06672f12fd794bf894342fa51100250bc6975806385
Users: 0x782b9ce19fe792ed3c4ccbfb439ab59ddc5369f2
Saving successful migration to network...
... 0x9e56386f94093c4f56f6b84190503376363f15a6d16661e7bfaa8fefe1b4be1f
Saving artifacts...
truffle(ganache)>
After the deployment you will see on Ganache some new transactions in the transaction list.
For the set up we are going to use Vue command line interface (Vue CLI): if you have not installed it yet here you can find the commands
$ npm install -g @vue/cli
$ npm install -g @vue/cli-init
Then type the following command to check if everything was installed correctly:
$ vue ––version
Now let's create a new project with the following command (you can create the project in any folder you want):
$ vue init webpack app-users
This command will start a wizard, which will ask you for general information like the app name, contact and description (just press enter).
On the question Install vue-router type Y for yes; type N for the questions:
? Project name apptest
? Project description A Vue.js project
? Author
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
Once the installation is done, go inside the folder of the project which has just been created:
$ cd app-users
And let's pull into the project the latest stable release of Web3.js (at the time of this writing):
$ npm install --save web3@0.20.6
Note that if you do not specify the version, npm will install the latest version of Web3.js (still in beta) and the dApp will not work.
Finally let's run the development server typing the following command in the project folder:
$ npm run dev
On the terminal you should see something like this:
Open the file index.html
in the root folder app-users
and paste the following CSS in the head section:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="/css/app.css">
The body has to include only the following tag:
<div id="app"></div>
The file index.html
should look like this:
https://github.com/danielefavi/ethereum-vuejs-dapp/blob/master/app-users/index.html
The folder app-users/src
contains the source of our project and now we are going to tweak it a little: delete the folder routes and create two folders called libs
and views
and finally create an empty file called routes.js
.
The structure of the folder src should be like this:
Our dApp uses the class BcExplorer to handle the interactions with the blockchain; BcExplorer makes easy the use of Web3j.js.
With BcExplorer you can:
The class BcExplorer is located in the app-users/src/libs
folder.
Note: the BcExplorer class works with the stable version of Web3.js 0.X but it does not work with the latest beta 1.x.
The file main.js
is the bootstrap file of our dApp: the only line of code added here is:
window.Event = new Vue();
It will help to handle the cross-components events.
As you can see from the main.js
, the first component that will be rendered is App.vue
.
App.vue
defines the structure of the pages with the menu on the top (TopMenu component) followed by the page content <router-view>
.
The content page will be displayed only when the connection with the blockchain is established successfully (bcConnected is true) and no error occurred (bcConnectionError is false).
<div class="main-content" v-show="bcConnected && !bcConnectionError">
<router-view></router-view>
</div>
NOTE: you can be successfully connected to the blockchain but the address of the smart contract might be wrong; bcConnectionError is a variable which indicates if general errors occurred with the blockchain.
Where are bcConnected and bcConnectionError defined? Where are the functions that handle the connection with the blockchain?
If you check the script section of App.vue
you will see that the mixin (click here to read mixin on Vue.js official documentation) mixinViews.js
is included: bcConnected and bcConnectionError are declared here.
In the mixin libs/mixinViews.js
are handled the set up of Web3.js and the initialization of the smart contracts; so all the components that use this mixin will initialize Web3.js and the smart contracts (if not initialized yet).
In the mixin you can see the declaration of the function created()
: when a component includes this mixin, the code within the created()
method in the mixin is mixed with the created()
method of the component.
The function created()
calls the method init()
. Following you can see the code of the method init()
in the mixin:
init() {
// when this file is imported to other component it checks if the BcExplorer
// is instatiated.
if (window.bc == undefined) {
window.bc = new BcExplorer;
// connecting to the blockchain and intializing the Users smart contract
window.bc.initWithContractJson(UsersContract, 'http://127.0.0.1:7545')
.then((error) => {
// handling the connection error
if (error) {
this.bcConnected = false;
this.showConnectionErrorMessage(error);
} else {
// calling a smart contract function in order to check the contract address
// is correct. NOTE: here you might be connected successfully.
this.isRegistered()
.then(res => {
this.bcConnectionError = false;
this.bcConnected = this.blockchainIsConnected();
})
.catch(error => {
this.showConnectionErrorMessage(error);
this.bcSmartContractAddressError = true;
});
}
})
.catch(error => this.showConnectionErrorMessage(error));
} // end if
},
The class BcExplorer is instantiated in window.bc
so it can be accessed everywhere.
In case you are wondering why the initialization of BcExplorer and Web3.js is in a mixin and not in the main.js.
I will give an example: you have a dApp with 10 pages and only in 2 of them you are using Web3.js; since you need Web3.js in 2 pages only, you can initialize Web3.js in one of those two pages instead of doing it everywhere in the main.js, which also slows down the initial loading.
This component shows the top menu. You can find this component in src/components/TopMenu.vue
.
The top menu shows:
If you check the code of this component you will see it includes the mixin mixinViews
. We need the BcExplorer functionalities because we have to check if the visitor is already registered and to show if the connection with the blockchain is established.
To show the message that the connection is established we can easily use the variable bcConnected defined in the mixin:
<strong :class="connectedClass">
{{ bcConnected ? 'Connected' : 'Not Connected' }}
</strong>
In the created method you can see that
Event.$on('userregistered', this.checkUntilUserIsRegistered);
this line of the code triggers the function checkUntilUserIsRegistered
when the event userregistered is fired. The function checkUntilUserIsRegistered
checks if the user is registered and it changes the link Register to Profile accordingly.
After the event userregistered is fired the function checkUntilUserIsRegistered
checks every second if the user has been registered successfully calling function isRegistered
(declarated in the mixinView.js):
isRegistered() {
return new Promise((resolve, reject) => {
window.bc.getMainAccount()
.then(account => {
window.bc.contract().isRegistered({ from: account }, (error, res) => {
if (error) reject(error);
resolve(res);
});
})
.catch(error => reject(error));
});
},
The function isRegistered()
first gets the user's account address calling the method getMainAccount()
. That function returns the account address (don't get confused with the coinbase address) through a promise. Once the promise from getMainAccount()
is received the smart contract function isRegistered
is called passing to it the account address as a parameter { from: account }
.
The checking stops when the block is mined and so the user is actually registered.
This control must be done every second (and not only once) because the mining of the block needs time.
Let me explain it with an example: let's suppose that your dApp uses a blockchain where the block mining is 5 minutes long; when a user signs up a transaction is submitted but it can take 5 minutes before the block is mined (so the user will be effectively registered).
If you are using Ganache the mining is instantaneous.
Another function in the created()
method is called: checkUserIsRegistered
.
This function changes the link from Register to Profile as well if the user is registered but the control is performed when the component is created.
This function has a timer too, that performs the check every half of a second, as connection to the blockchain can require some time; the checking stops when a response is received.
Let's check the main functions used in the views.
In the file List.vue
you can see all the status of the registered user. Below you can see the function that retrieves all the registered users:
getAllUsers(callback) {
// getting the total number of users stored in the blockchain
// calling the method totalUsers from the smart contract
window.bc.contract().totalUsers((err, total) => {
var tot = 0;
if (total) tot = total.toNumber();
if (tot > 0) {
// getting the user one by one
for (var i=1; i<=tot; i++) {
window.bc.contract().getUserById.call(i, (error, userProfile) => {
callback(userProfile);
});
} // end for
} // end if
}); // end totalUsers call
}
This method first calls the smart contract function totalUsers
to get the total number of users; then it gets all the users one by one calling the smart contract function getUserById
starting with the user with ID 1 to the user with the ID returned by totalUsers
function.
When the user is on the registration page (file Register.vue
) and he presses the Register button the function performSubmit()
is triggered. performSubmit()
calls the function performUserRegistration()
that performs the actual user registration:
performUserRegistration(address) {
window.bc.contract().registerUser(
this.userName,
this.userStatus,
{
from: address,
gas: 800000
},
(err, txHash) => {
this.submitting = false;
if (err) {
this.showErrorMessage(err);
}
else {
this.successMessage = true;
// it emits a global event in order to update the top menu bar
Event.$emit('userregistered', txHash);
// the transaction was submitted and the user will be redirected to the
// profile page once the block will be mined
this.redirectWhenBlockMined();
}
}
)
},
As you can see, the smart contract function registerUser
to register a user is called. The function must receive 3 parameters:
If the registration is successful a global event userregistered will be fired:
Event.$emit('userregistered', txHash);
This event will be caught by the TopMenu
component as described before.
Then redirectWhenBlockMined()
is triggered: this method waits until the block is mined then it redirects the user to its own profile page_
#blockchain #dapp #vuejs #javascript #solidity #ethereum #smartcontract
1652211960
A set of helper methods to help query ETH smart contracts
If available in Hex, the package can be installed by adding eth_contract
to your list of dependencies in mix.exs
:
def deps do
[
{:eth_contract, "~> 0.1.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/eth_contract.
Add your JSON RPC provider URL in config.exs
config :ethereumex,
url: "http://"
Load and parse the ABI
abi = EthContract.parse_abi("crypto_kitties.json")
Get meta given a token_id and method name
EthContract.meta(%{token_id: 45, method: "getKitty", contract: "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d", abi: abi})
This will return a map with all the meta:
%{ "birthTime" => 1511417999,
"cooldownIndex" => 0,
"generation" => 0,
"genes" => 626837621154801616088980922659877168609154386318304496692374110716999053,
"isGestating" => false,
"isReady" => true,
"matronId" => 0,
"nextActionAt" => 0,
"sireId" => 0,
"siringWithId" => 0
}
Download Details:
Author: zyield
Source Code: https://github.com/zyield/eth_contract
License: GPL-3.0 license
1652204640
Elixir JSON-RPC client for the Ethereum blockchain.
Check out the documentation here.
Add :ethereumex
to your list of dependencies in mix.exs
:
def deps do
[
{:ethereumex, "~> 0.9"}
]
end
Ensure :ethereumex
is started before your application:
def application do
[
applications: [:ethereumex]
]
end
In config/config.exs
, add Ethereum protocol host params to your config file
config :ethereumex,
url: "http://localhost:8545"
You can also configure the HTTP
request timeout for requests sent to the Ethereum JSON-RPC (you can also overwrite this configuration in opts
used when calling the client).
config :ethereumex,
http_options: [pool_timeout: 5000, receive_timeout: 15_000],
http_headers: [{"Content-Type", "application/json"}]
:pool_timeout
- This timeout is applied when we check out a connection from the pool. Default value is 5_000
. :receive_timeout
- The maximum time to wait for a response before returning an error. Default value is 15_000
If you want to use IPC you will need to set a few things in your config.
First, specify the :client_type
:
config :ethereumex,
client_type: :ipc
This will resolve to :http
by default.
Second, specify the :ipc_path
:
config :ethereumex,
ipc_path: "/path/to/ipc"
If you want to count the number of RPC calls per RPC method or overall, you can attach yourself to executed telemetry events. There are two events you can attach yourself to: [:ethereumex]
# has RPC method name in metadata Emitted event: {:event, [:ethereumex], %{counter: 1}, %{method_name: "method_name"}}
or more granular [:ethereumex, <rpc_method>]
# %{} metadata Emitted event: {:event, [:ethereumex, :method_name_as_atom], %{counter: 1}, %{}}
Each event caries a single ticker that you can pass into your counters (like Statix.increment/2
). Be sure to add :telemetry as project dependency.
The IPC client type mode opens a pool of connection workers (default is 5 and 2, respectively). You can configure the pool size.
config :ethereumex,
ipc_worker_size: 5,
ipc_max_worker_overflow: 2,
ipc_request_timeout: 60_000
Download parity
and initialize the password file
$ make setup
Run parity
$ make run
Run tests
$ make test
web3_clientVersion
web3_sha3
net_version
net_peerCount
net_listening
eth_protocolVersion
eth_syncing
eth_coinbase
eth_mining
eth_hashrate
eth_gasPrice
eth_accounts
eth_blockNumber
eth_getBalance
eth_getStorageAt
eth_getTransactionCount
eth_getBlockTransactionCountByHash
eth_getBlockTransactionCountByNumber
eth_getUncleCountByBlockHash
eth_getUncleCountByBlockNumber
eth_getCode
eth_sign
eth_sendTransaction
eth_sendRawTransaction
eth_call
eth_estimateGas
eth_getBlockByHash
eth_getBlockByNumber
eth_getTransactionByHash
eth_getTransactionByBlockHashAndIndex
eth_getTransactionByBlockNumberAndIndex
eth_getTransactionReceipt
eth_getUncleByBlockHashAndIndex
eth_getUncleByBlockNumberAndIndex
eth_getCompilers
eth_compileLLL
eth_compileSolidity
eth_compileSerpent
eth_newFilter
eth_newBlockFilter
eth_newPendingTransactionFilter
eth_uninstallFilter
eth_getFilterChanges
eth_getFilterLogs
eth_getLogs
eth_getWork
eth_submitWork
eth_submitHashrate
db_putString
db_getString
db_putHex
db_getHex
shh_post
shh_version
shh_newIdentity
shh_hasIdentity
shh_newGroup
shh_addToGroup
shh_newFilter
shh_uninstallFilter
shh_getFilterChanges
shh_getMessages
You can follow along with any of these examples using IPC by replacing HttpClient
with IpcClient
.
iex> Ethereumex.HttpClient.web3_client_version
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}
# Using the url option will overwrite the configuration
iex> Ethereumex.HttpClient.web3_client_version(url: "http://localhost:8545")
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}
iex> Ethereumex.HttpClient.web3_sha3("wrong_param")
{:error, %{"code" => -32602, "message" => "Invalid params: invalid format."}}
iex> Ethereumex.HttpClient.eth_get_balance("0x407d73d8a49eeb85d32cf465507dd71d507100c1")
{:ok, "0x0"}
Note that all method names are snakecases, so, for example, shh_getMessages method has corresponding Ethereumex.HttpClient.shh_get_messages/1 method. Signatures can be found in Ethereumex.Client.Behaviour. There are more examples in tests.
In order to call a smart contract using the JSON-RPC interface you need to properly hash the data attribute (this will need to include the contract method signature along with arguments if any). You can do this manually or use a hex package like ABI to parse your smart contract interface or encode individual calls.
defp deps do
[
...
{:ethereumex, "~> 0.9"},
{:ex_abi, "~> 0.5"}
...
]
end
Now load the ABI and pass the method signature. Note that the address needs to be converted to bytes:
address = "0xF742d4cE7713c54dD701AA9e92101aC42D63F895" |> String.slice(2..-1) |> Base.decode16!(case: :mixed)
contract_address = "0xC28980830dD8b9c68a45384f5489ccdAF19D53cC"
abi_encoded_data = ABI.encode("balanceOf(address)", [address]) |> Base.encode16(case: :lower)
Now you can use eth_call to execute this smart contract command:
balance_bytes = Ethereumex.HttpClient.eth_call(%{
data: "0x" <> abi_encoded_data,
to: contract_address
})
To convert the balance into an integer:
balance_bytes
|> String.slice(2..-1)
|> Base.decode16!(case: :lower)
|> TypeDecoder.decode_raw([{:uint, 256}])
|> List.first
Many Ethereum protocol implementations support additional JSON-RPC API methods. To use them, you should call Ethereumex.HttpClient.request/3 method.
For example, let's call parity's personal_listAccounts method.
iex> Ethereumex.HttpClient.request("personal_listAccounts", [], [])
{:ok,
["0x71cf0b576a95c347078ec2339303d13024a26910",
"0x7c12323a4fff6df1a25d38319d5692982f48ec2e"]}
To send batch requests use Ethereumex.HttpClient.batch_request/1 or Ethereumex.HttpClient.batch_request/2 method.
requests = [
{:web3_client_version, []},
{:net_version, []},
{:web3_sha3, ["0x68656c6c6f20776f726c64"]}
]
Ethereumex.HttpClient.batch_request(requests)
{
:ok,
[
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"},
{:ok, "42"},
{:ok, "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"}
]
}
If you are curious what others are building with ethereumex, you might want to take a look at these projects:
exw3 - A high-level contract abstraction and other goodies similar to web3.js
eth - Ethereum utilities for Elixir.
eth_contract - A set of helper methods for calling ETH Smart Contracts via JSON RPC.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Download Details:
Author: mana-ethereum
Source Code: https://github.com/mana-ethereum/ethereumex
License: MIT license
#blockchain #solidity #ethereum #smartcontract #elixir #json #JSONrpc
1652197200
An Ethereum event listener that bridges your smart contract events and backend microservices. Eventeum listens for specified event emissions from the Ethereum network, and broadcasts these events into your middleware layer. This provides a distinct separation of concerns and means that your microservices do not have to subscribe to events directly to an Ethereum node.
Dynamically Configurable - Eventeum exposes a REST api so that smart contract events can be dynamically subscribed / unsubscribed.
Highly Available - Eventeum instances communicate with each other to ensure that every instance is subscribed to the same collection of smart contract events.
Resilient - Node failures are detected and event subscriptions will continue from the failure block once the node comes back online.
Fork Tolerance - Eventeum can be configured to wait a certain amount of blocks before an event is considered 'Confirmed'. If a fork occurs during this time, a message is broadcast to the network, allowing your services to react to the forked/removed event.
For RabbitMQ, you can configure the following extra values
Follow the instructions below in order to run Eventeum on your local machine for development and testing purposes.
$ cd /path/to/eventeum/
2. Compile, test and package the project
$ mvn clean package
a. If you have a running instance of MongoDB, Kafka, Zookeeper and an Ethereum node:
Executable JAR:
$ cd server
$ export SPRING_DATA_MONGODB_HOST=<mongodb-host:port>
$ export ETHEREUM_NODE_URL=http://<node-host:port>
$ export ZOOKEEPER_ADDRESS=<zookeeper-host:port>
$ export KAFKA_ADDRESSES=<kafka-host:port>
$ export RABBIT_ADDRESSES=<rabbit-host:port>
$ java -jar target/eventeum-server.jar
Docker:
$ cd server
$ docker build . -t kauri/eventeum:latest
$ export SPRING_DATA_MONGODB_HOST=<mongodb-host:port>
$ export ETHEREUM_NODE_URL=http://<node-host:port>
$ export ZOOKEEPER_ADDRESS=<zookeeper-host:port>
$ export KAFKA_ADDRESSES=<kafka-host:port>
$ export RABBIT_ADDRESSES=<rabbit-host:port>
$ docker run -p 8060:8060 kauri/eventeum
b. If you prefer build an all-in-one test environment with a parity dev node, use docker-compose:
$ cd server
$ docker-compose -f docker-compose.yml build
$ docker-compose -f docker-compose.yml up
Eventeum now supports a SQL database as well as the default MongoDB. To use a SQL database (only SQL Server has currently been tested but others should be supported with the correct config), set the database.type
property to SQL
and ensure you have all required additional properties in your properties file. See config-examples/application-template-sqlserver.yml
for a sample SQLServer configuration.
When upgrading Eventeum to 0.8.0, changes in the schema are required. In order to perform the migration follow these steps:
Listening for events from multiple different nodes is supported in Eventeum, and these nodes can be configured in the properties file.
ethereum:
nodes:
- name: default
url: http://mainnet:8545
- name: sidechain
url: wss://sidechain/ws
If an event does not specify a node, then it will be registered against the 'default' node.
That is the simplest node configuration, but there is other custom flags you can activate per node:
maxIdleConnections
: Maximum number of connections to the node. (default: 5)keepAliveDuration
: Duration of the keep alive http in milliseconds (default: 10000)connectionTimeout
: Http connection timeout to the node in milliseconds (default: 5000)readTimeout
: Http read timeout to the node in milliseconds (default: 60000)addTransactionRevertReason
: Enables receiving the revert reason when a transaction fails. (default: false)pollInterval
: Polling interval of the rpc request to the node (default: 10000)healthcheckInterval
: Polling interval of that evenreum will use to check if the node is active (default: 10000)numBlocksToWait
: Blocks to wait until we decide event is confirmed (default: 1). Overrides broadcaster confignumBlocksToWaitBeforeInvalidating
: Blocks to wait until we decide event is invalidated (default: 1). Overrides broadcaster confignumBlocksToWaitForMissingTx
: Blocks to wait until we decide tx is missing (default: 1) Overrides broadcaster configThis will be an example with a complex configuration:
ethereum:
nodes:
- name: default
url: http://mainnet:8545
pollInterval: 1000
maxIdleConnections: 10
keepAliveDuration: 15000
connectionTimeout: 7000
readTimeout: 35000
healthcheckInterval: 3000
addTransactionRevertReason: true
numBlocksToWait: 1
numBlocksToWaitBeforeInvalidating: 1
numBlocksToWaitForMissingTx: 1
blockStrategy: POLL
Eventeum exposes a REST api that can be used to register events that should be subscribed to / broadcast.
/api/rest/v1/event-filter
POST
Key | Value |
---|---|
content-type | application/json |
N/A
{
"id": "event-identifier",
"contractAddress": "0x1fbBeeE6eC2B7B095fE3c5A572551b1e260Af4d2",
"eventSpecification": {
"eventName": "TestEvent",
"indexedParameterDefinitions": [
{"position": 0, "type": "UINT256"},
{"position": 1, "type": "ADDRESS"}],
"nonIndexedParameterDefinitions": [
{"position": 2, "type": "BYTES32"},
{"position": 3, "type": "STRING"}] },
"correlationIdStrategy": {
"type": "NON_INDEXED_PARAMETER",
"parameterIndex": 0 }
}
Name | Type | Mandatory | Default | Description |
---|---|---|---|---|
id | String | no | Autogenerated | A unique identifier for the event. |
contractAddress | String | yes | The address of the smart contract that the address will be emitted from. | |
eventSpecification | json | yes | The event specification | |
correlationIdStrategy | json | no | null | Define a correlation id for the event (only used with the Kafka broadcaster). See the advanced section for details. |
eventSpecification:
Name | Type | Mandatory | Default | Description |
---|---|---|---|---|
eventName | String | yes | The event name within the smart contract | |
indexedParameterTypes | String array | no | null | The array of indexed parameter types for the event. |
nonIndexedParameterTypes | String array | no | null | The array of non-indexed parameter types for the event. |
parameterDefinition:
Name | Type | Mandatory | Default | Description |
---|---|---|---|---|
position | Number | yes | The zero indexed position of the parameter within the event specification | |
type | String | yes | The type of the event parameter. |
Currently supported parameter types: UINT8-256
, INT8-256
, ADDRESS
, BYTES1-32
, STRING
, BOOL
.
Dynamically sized arrays are also supported by suffixing the type with []
, e.g. UINT256[]
.
correlationIdStrategy:
Name | Type | Mandatory | Default | Description |
---|---|---|---|---|
type | String | yes | The correlation id strategy type. | |
parameterIndex | Number | yes | The parameter index to use within the correlation strategy. |
{
"id": "event-identifier"
}
Static events can be configured within the application.yml file of Eventeum.
eventFilters:
- id: RequestCreated
contractAddress: ${CONTRACT_ADDRESS:0x4aecf261541f168bb3ca65fa8ff5012498aac3b8}
eventSpecification:
eventName: RequestCreated
indexedParameterDefinitions:
- position: 0
type: BYTES32
- position: 1
type: ADDRESS
nonIndexedParameterDefinitions:
- position: 2
type: BYTES32
correlationId:
type: NON_INDEXED_PARAMETER
index: 0
URL: /api/rest/v1/event-filter/{event-id}
Method: DELETE
Headers: N/A
URL Params: N/A
Body: N/A
Success Response:
N/A
/api/rest/v1/event-filter
GET
Key | Value |
---|---|
accept | application/json |
N/A
[{
"id": "event-identifier-1",
"contractAddress": "0x1fbBeeE6eC2B7B095fE3c5A572551b1e260Af4d2",
"eventSpecification": {
"eventName": "TestEvent",
"indexedParameterDefinitions": [
{"position": 0, "type": "UINT256"},
{"position": 1, "type": "ADDRESS"}],
"nonIndexedParameterDefinitions": [
{"position": 2, "type": "BYTES32"},
{"position": 3, "type": "STRING"}] },
"correlationIdStrategy": {
"type": "NON_INDEXED_PARAMETER",
"parameterIndex": 0 }
},
....
{
"id": "event-identifier-N",
"contractAddress": "0x1fbBeeE6eC2B7B095fE3c5A572551b1e260Af4d2",
"eventSpecification": {
"eventName": "TestEvent",
"indexedParameterDefinitions": [
{"position": 0, "type": "UINT256"},
{"position": 1, "type": "ADDRESS"}],
"nonIndexedParameterDefinitions": [
{"position": 2, "type": "BYTES32"},
{"position": 3, "type": "STRING"}] },
"correlationIdStrategy": {
"type": "NON_INDEXED_PARAMETER",
"parameterIndex": 0 }
}
]
From version 0.6.2, eventeum supports monitoring and broadcasting transactions. The matching criteria can be:
Besides on that, it can monitor the transaction for specific statuses:
To register a transaction monitor, use the below REST endpoint:
/api/rest/v1/transaction?identifier=<txHash>&nodeName=<nodeName>
POST
N/A
N/A
An example with type HASH
:
{
"type": "HASH",
"transactionIdentifierValue": "0x2e8e0f98be22aa1251584e23f792d43c634744340eb274473e01a48db939f94d",
"nodeName": "defaultNetwork",
"statuses": ["FAIlED", "CONFIRMATION"]
}
Example filtering by FROM_ADDRES
, this will notify when a transactions fails with origin the address specified in the field transactionIdentifierValue
{
"type": "FROM_ADDRESS" ,
"transactionIdentifierValue": "0x1fbBeeE6eC2B7B095fE3c5A572551b1e260Af4d2",
"nodeName": "defaultNetwork",
"statuses": ["FAIlED"]
}
Name | Type | Mandatory | Default | Description |
---|---|---|---|---|
type | String | yes | The type of the filter you want to create: HASH , FROM_ADDRESS , TO_ADDRESS | |
transactionIdentifierValue | String | yes | The value associated with the type. It should be the tx hash for HASH and the address of the contract in the other cases. | |
nodeName | String | yes | default | The identifier of the node you want to listen the transaction |
statuses | List | no | ['FAILED', 'CONFIRMED'] | It will specify the statuses you want to be notified. The default is failed and confirmed transactions. The options are: FAILED , CONFIRMED , UNCONFIRMED , INVALIDATED |
{
"id": "transaction-monitor-identifier"
}
URL: /api/rest/v1/transaction/{monitor-id}
Method: DELETE
Headers: N/A
URL Params: N/A
Body: N/A
Success Response:
N/A
When a subscribed event is emitted, a JSON message is broadcast to the configured kafka topic or rabbit exchange (contract-events by default), with the following format:
{
"id":"unique-event-id",
"type":"CONTRACT_EVENT",
"details":{
"name":"DummyEvent",
"filterId":"63da468c-cec6-49aa-bea4-eeba64fb1df4",
"indexedParameters":[{"type":"bytes32","value":"BytesValue"},
{"type":"address","value":"0x00a329c0648769a73afac7f9381e08fb43dbea72"}],
"nonIndexedParameters":[{"type":"uint256","value":10},
{"type":"string","value":"StringValue"}],
"transactionHash":"0xe4fd0f095990ec471cdf40638336a73636d2e88fc1a240c20b45101b9cce9438",
"logIndex":0,
"blockNumber":258,
"blockHash":"0x65d1956c2850677f75ec9adcd7b2cfab89e31ad1e7a5ba93b6fad11e6cd15e4a",
"address":"0x9ec580fa364159a09ea15cd39505fc0a926d3a00",
"status":"UNCONFIRMED",
"eventSpecificationSignature":"0x46aca551d5bafd01d98f8cadeb9b50f1b3ee44c33007f2a13d969dab7e7cf2a8",
"id":"unique-event-id"},
"retries":0
}
When a new block is mined, a JSON message is broadcast to the configured kafka topic or rabbit exchange (block-events by default), with the following format:
{
"id":"0x79799054d1782eb4f246b3055b967557148f38344fbd7020febf7b2d44faa4f8",
"type":"BLOCK",
"details":{
"number":257,
"hash":"0x79799054d1782eb4f246b3055b967557148f38344fbd7020febf7b2d44faa4f8",
"timestamp":12345678},
"retries":0
}
When a new transaction that matches a transaction monitor is mined, a JSON message is broadcast to the configured kafka topic or rabbit exchange (transaction-events by default), with the following format:
{
"id":"0x1c0482642861779703a34f4539b3ba18a0fddfb16558f3be7157fdafcaf2c030",
"type":"TRANSACTION",
"details":{
"hash":"0x1c0482642861779703a34f4539b3ba18a0fddfb16558f3be7157fdafcaf2c030",
"nonce":"0xf",
"blockHash":"0x6a68edf369ba4ddf93aa31cf5871ad51b5f7988a69f1ddf9ed09ead8b626db48",
"blockNumber":"0x1e1",
"transactionIndex":"0x0",
"from":"0xf17f52151ebef6c7334fad080c5704d77216b732",
"to":"0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef",
"value":"0x16345785d8a0000",
"nodeName":"default",
"status":"CONFIRMED"},
"retries":0
}
If the transaction is a contract creation transaction, then the contractAddress
value will be set to the address of the newly deployed smart contract.
A broadcast transaction event can have the following statuses:
Status | Description |
---|---|
UNCONFIRMED | Transaction has been mined and we're now waiting for the configured number of blocks |
CONFIRMED | The configured number of blocks have been mined since the transaction has been mined |
INVALIDATED | The blockchain has forked since the initially broadcast UNCONFIRMED transaction was broadcast |
FAILED | The transaction has been mined but the tx execution failed |
Eventeum can either be configured by:
application.yml
next to the built JAR (copy one from config-examples
). This overlays the defaults from server/src/main/resources/application.yml
.Env Variable | Default | Description |
---|---|---|
SERVER_PORT | 8060 | The port for the eventeum instance. |
ETHEREUM_BLOCKSTRATEGY | POLL | The strategy for obtaining block events from an ethereum node (POLL or PUBSUB). It will be overwritten by the specific node configuration. |
ETHEREUM_NODE_URL | http://localhost:8545 | The default ethereum node url. |
ETHEREUM_NODE_BLOCKSTRATEGY | POLL | The strategy for obtaining block events for the ethereum node (POLL or PUBSUB). |
ETHEREUM_NODE_HEALTHCHECK_POLLINTERVAL | 2000 | The interval time in ms, in which a request is made to the ethereum node, to ensure that the node is running and functional. |
ETHEREUM_NODE_ADD_TRANSACTION_REVERT_REASON | false | In case of a failing transaction it indicates if Eventeum should get the revert reason. Currently not working for Ganache and Parity. |
ETHEREUM_NUMBLOCKSTOREPLAY | 12 | Number of blocks to replay on node or service failure (ensures no blocks / events are missed on chain reorg) |
POLLING_INTERVAL | 10000 | The polling interval used by Web3j to get events from the blockchain. |
EVENTSTORE_TYPE | DB | The type of eventstore used in Eventeum. (See the Advanced section for more details) |
BROADCASTER_TYPE | KAFKA | The broadcast mechanism to use. (KAFKA or HTTP or RABBIT) |
BROADCASTER_CACHE_EXPIRATIONMILLIS | 6000000 | The eventeum broadcaster has an internal cache of sent messages, which ensures that duplicate messages are not broadcast. This is the time that a message should live within this cache. |
BROADCASTER_EVENT_CONFIRMATION_NUMBLOCKSTOWAIT | 12 | The number of blocks to wait (after the initial mined block) before broadcasting a CONFIRMED event |
BROADCASTER_EVENT_CONFIRMATION_NUMBLOCKSTOWAITFORMISSINGTX | 200 | After a fork, a transaction may disappear, and this is the number of blocks to wait on the new fork, before assuming that an event emitted during this transaction has been INVALIDATED |
BROADCASTER_EVENT_CONFIRMATION_NUMBLOCKSTOWAITBEFOREINVALIDATING | 2 | Number of blocks to wait before considering a block as invalid. |
BROADCASTER_MULTIINSTANCE | false | If multiple instances of eventeum are to be deployed in your system, this should be set to true so that the eventeum communicates added/removed filters to other instances, via kafka. |
BROADCASTER_HTTP CONTRACTEVENTSURL | The http url for posting contract events (for HTTP broadcasting) | |
BROADCASTER_HTTP BLOCKEVENTSURL | The http url for posting block events (for HTTP broadcasting) | |
BROADCASTER_BYTESTOASCII | false | If any bytes values within events should be converted to ascii (default is hex) |
BROADCASTER_ENABLE_BLOCK_NOTIFICATION | true | Boolean that indicates if want to receive block notifications or not. Set false to not receive that event. |
ZOOKEEPER_ADDRESS | localhost:2181 | The zookeeper address |
KAFKA_ADDRESSES | localhost:9092 | Comma seperated list of kafka addresses |
KAFKA_TOPIC_CONTRACT_EVENTS | contract-events | The topic name for broadcast contract event messages |
KAFKA_TOPIC_BLOCK_EVENTS | block-events | The topic name for broadcast block event messages |
KAFKA_TOPIC_TRANSACTION_EVENTS | transaction-events | The topic name for broadcast trasaction messages |
KAFKA_REQUEST_TIMEOUT_MS | 20000 | The duration after which a request timeouts |
KAFKA_ENDPOINT_IDENTIFICATION_ALGORITHM | null | The endpoint identification algorithm to validate server hostname using server certificate |
KAFKA_SASL_MECHANISM | PLAIN | The mechanism used for SASL authentication |
KAFKA_USERNAME | "" | The username used to connect to a SASL secured Kafka cluster |
KAFKA_PASSWORD | "" | The password used to connect to a SASL secured Kafka cluster |
KAFKA_SECURITY_PROTOCOL | PLAINTEXT | Protocol used to communicate with Kafka brokers |
KAFKA_RETRIES | 10 | The number of times a Kafka consumer will try to publish a message before throwing an error |
KAFKA_RETRY_BACKOFF_MS | 500 | The duration between each retry |
KEEP_ALIVE_DURATION | 15000 | Rpc http idle threads keep alive timeout in ms |
MAX_IDLE_CONNECTIONS | 10 | The max number of HTTP rpc idle threads at the pool |
SYNCINC_THRESHOLD | 60 | Number of blocks of difference to consider that eventeum is "syncing" with a node |
SPRING_DATA_MONGODB_HOST | localhost | The mongoDB host (used when event store is set to DB) |
SPRING_DATA_MONGODB_PORT | 27017 | The mongoDB post (used when event store is set to DB) |
RABBIT_ADDRESS | localhost:5672 | property spring.rabbitmq.host (The rabbitmq address) |
RABBIT_EXCHANGE | ThisIsAExchange | property rabbitmq.exchange |
RABBIT_ROUTING_KEY | thisIsRoutingKey | property rabbitmq.routingKeyPrefix |
DATABASE_TYPE | MONGO | The database to use. Either MONGO or SQL. |
CONNECTION_TIMEOUT | 7000 | RPC, http connection timeout in millis |
READ_TIMEOUT | 35000 | RPC, http read timeout in millis |
Connecting to an INFURA node is only supported if connecting via websockets (wss://<...>
node url). The blockstrategy must also be set to PUBSUB.
Each subscribed event can have a correlation id strategy association with it, during subscription. A correlation id strategy defines what the kafka message key for a broadcast event should be, and allows the system to be configured so that events with particular parameter values are always sent to the same partition.
Currently supported correlation id strategies are:
Indexed Parameter Strategy - An indexed parameter within the event is used as the message key when broadcasting. Non Indexed Parameter Strategy - An non-indexed parameter within the event is used as the message key when broadcasting.
Eventeum utilises an event store in order to establish the block number to start event subscriptions from, in the event of a failover. For example, if the last event broadcast for event with id X had a block number of 123, then on a failover, eventeum will subscribe to events from block 124.
There are currently 2 supported event store implementations:
Broadcast events are saved and retrieved from a mongoDB database.
Required Configuration
Env Variable | Default | Description |
---|---|---|
EVENTSTORE_TYPE | DB | MongoDB event store enabled |
SPRING_DATA_MONGODB_HOST | localhost | The mongoDB host |
SPRING_DATA_MONGODB_PORT | 27017 | The mongoDB post |
Eventeum polls an external REST service in order to obtain a list of events broadcast for a specific event specification. It is assumed that this REST service listens for broadcast events on the kafka topic and updates its internal state...broadcast events are not directly sent to the REST service by eventeum.
The implemented REST service should have a pageable endpoint which accepts a request with the following specification:
/api/rest/v1/event
GET
Key | Value |
---|---|
content-type | application/json |
Key | Value |
---|---|
page | The page number |
size | The page size |
sort | The results sort field |
dir | The results sort direction |
signature | Retrieve events with the specified event signature |
Body: N/A
Success Response:
{
"content":[
{"blockNumber":10,"id":<unique event id>}],
"page":1,
"size":1,
"totalElements":1,
"first":false,
"last":true,
"totalPages":1,
"numberOfElements":1,
"hasContent":true
}
Required Configuration
Env Variable | Default | Description |
---|---|---|
EVENTSTORE_TYPE | REST | REST event store enabled |
EVENTSTORE_URL | http://localhost:8081/api/rest/v1 | The REST endpoint url |
EVENTSTORE_EVENTPATH | /event | The path to the event REST endpoint |
Eventeum can be embedded into an existing Spring Application via an annotation.
pom.xml
file:<repositories>
<repository>
<id>eventeum-artifactory</id>
<url>https://eventeum.jfrog.io/artifactory/eventeum</url>
</repository>
</repositories>
2. Add the eventeum-core dependency to your pom.xml
file:
<dependency>
<groupId>io.eventeum</groupId>
<artifactId>eventeum-core</artifactId>
<version>*LATEST_EVENTEUM_VERSION*</version>
</dependency>
3. Within your Application class or a @Configuration
annotated class, add the @EnableEventeum
annotation.
Eventeum offers a healthcheck url where you can ask for the status of the systems you are using. It will look like:
{
"status":"UP",
"details":{
"rabbit":{
"status":"UP",
"details":{
"version":"3.7.13"
}
},
"mongo":{
"status":"UP",
"details":{
"version":"4.0.8"
}
}
}
}
Returning this information it is very easy to create alerts over the status of the system.
The endpoint is: GET /monitoring/health
Eventeum includes a prometheus metrics export endpoint.
It includes standard jvm, tomcat metrics enabled by spring-boot https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-metrics-export-prometheus https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-metrics-meter.
Added to the standard metrics, custom metrics have been added:
All metrics include application="Eventeum",environment="local" tags.
The endpoint is: GET /monitoring/prometheus
Download Details:
Author: eventeum
Source Code: https://github.com/eventeum/eventeum
License: Apache-2.0 license
1652189640
This is a Kotlin library for Ethereum. It is striving towards being 100% Kotlin (the code in the lib is Kotlin anyway - but also trying to not drag in JVM dependencies). This is done in order to enable multi-platform support in the future. Currently this library is mainly used in JVM projects but could this way also target e.g. JavaScript and WebAssembly that are broadly used in the web3 space. Another core principle of this library is to be as modular as possible. Ethereum has a wide range of use-cases and should not be supported by huge monolithic libraries. With KEthereum you can pick and choose the modules you need and keep the footprint of the library small this way.
Name | Description | Status | Documentation |
---|---|---|---|
abi | Application Binary Interface (ABI) for contracts | beta | |
abi_codegen | Kotlin code generation from ABIs | beta | |
abi_filter | Functions for filtering ABIs | beta | |
blockscout | BlockScout BlockExplorer helper functions | beta | |
bloomfilter | Space-efficient probabilistic data structure | beta | |
eip137 | Model and functions for ENS NameHash | beta | |
eip155 | TX signing with Simple replay attack protection | production | example code |
eip191 | Functions to sign data via signed data standard | beta | |
eip712 | Ethereum typed structured data hashing and signing | experimental | |
ens | ENS (Ethereum Name Service) functionality | beta | README |
erc1328 | WalletConnect Standard URI Format | beta | |
erc1450 | ERC-20 extension - e.g. including token minting | beta | example code |
erc181 | ENS reverse resolution of addresses | beta | |
erc20 | Contract wrapper for the ERC20 Token standard | beta | |
erc55 | Mixed-case checksum address encoding | production | README |
erc634 | Storage of text records in ENS | beta | README |
erc67 | Standard URI scheme for transactions | beta | |
erc681 | URL Format for Transaction Requests (successor of ERC67) | beta | |
erc831 | URI Format for Ethereum (used by 681, 961, ..) | beta | |
erc961 | URI standard for tokens | beta | |
etherscan | EtherScan BlockExplorer function | beta | |
example_cli | CLI App to demo KEthereum functionality | demonstration | example code |
extensions_kotlin | Extension functions for Kotlin types | beta | |
extensions_transactions | Extension functions for the Transaction class | beta | |
flows | Coroutine flows for blocks and transactions | beta | example code |
keccak_shortcut | Proxy extension function for keccak hashing | beta | |
keystore | Storage for wallet files (e.g. to use the geth keystore) | beta | |
metadata | Model and parser for contract metadata | beta | |
method_signatures | Functionality for method signatures (4byte repository,..) | beta | |
model | Data-/Inline-Classes and constants | beta | |
rlp | Recursive Length Prefix (RLP) encoder/decoder | beta | |
rpc | Remote Procedure Calls (RPC) abstraction | beta | |
rpc_min3 | Minimal INCUBED (IN3) RPC | experimental | README |
test_data | Data used in KEthereum tests | production | - |
types | Handling of EVM types (e.g. used code from abi_codegen ) | beta | |
uri_common | Used by several URI modules (681, 1328, 961, ..) | beta | |
wallet | functions for keys from and to JSON wallet files | beta |
KEthereum is available via jitpack:
Download Details:
Author: komputing
Source Code: https://github.com/komputing/KEthereum
License: MIT license
1652182260
The goal of ethereum.rb is to make interacting with the Ethereum blockchain from Ruby as fast and easy as possible (but not easier!).
Project is currently maintained by @kurotaky.
Before installing the gem make sure you meet all prerequisites, especially that you have:
Before you run a program check that the node is running and accounts you want to spend from are unlocked.
To install gem simply add this line to your application's Gemfile:
gem 'ethereum.rb'
And then execute:
$ bundle
Or install it yourself as:
$ gem install ethereum.rb
You can create a contract from solidity source and deploy it to the blockchain, with the following code:
contract = Ethereum::Contract.create(file: "greeter.sol")
address = contract.deploy_and_wait("Hello from ethereum.rb!")
Deployment may take up to a couple of minutes. Once deployed you can start interacting with the contract, e.g. calling it's methods:
contract.call.greet # => "Hello from ethereum.rb!"
You can see example contract greeter here.
If contract method name uses camel case you must convert it to snake case when use call:
call.your_method
.
If you want to complie multiple contracts at once, you can create new instances using newly declared ruby clasess:
Ethereum::Contract.create(file: "mycontracts.sol", client: client)
contract = MyContract1.new
contract = contract.deploy_and_wait
contract2 = MyContract2.new
contract2 = contract.deploy_and_wait
All names used to name contract in solidity source will translate to name of classes in ruby (camelized).
Note: If class of given name exist it will be undefined first to avoid name collision.
The other way to obtain a contract instance is to get one that already exists on the blockchain. To do so you need a contract name, contract address and ABI definition.
contract = Ethereum::Contract.create(name: "MyContract", address: "0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd ", abi: abi)
Note that you need to specify a contract name, that will be used to define new class in ruby, as it is not a part of the ABI definition.
Alternatively you can obtain the abi definition and name from a contract source file:
contract = Ethereum::Contract.create(file: "MyContract.sol", address: "0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd ")
If you want to create a new contract, that is not yet deployed from ABI definition you will need also to supply binary code:
contract = Ethereum::Contract.create(name: "MyContract", abi: abi, code: "...")
If you use Truffle to build and deploy contracts, you can pick up the Truffle artifacts to initialize a contract. For example, if you have a MyContract in the Truffle directory at /my/truffle/project
:
contract = Ethereum::Contract.create(name: "MyContract", truffle: { paths: [ '/my/truffle/project' ] }, client: client, address: '0x01a4d1A62F01ED966646acBfA8BB0b59960D06dd')
The contract factory will attempt to load the deployed address from the Truffle artifacts if the client's network is present:
contract = Ethereum::Contract.create(name: "MyContract", truffle: { paths: [ '/my/truffle/project' ] }, client: client)
Functions defined in a contract are exposed using the following conventions:
contract.transact.[function_name](params)
contract.transact_and_wait.[function_name](params)
contract.call.[function_name](params)
Example Contract in Solidity
contract SimpleRegistry {
event LogRegister(bytes32 key, string value);
mapping (bytes32 => string) public registry;
function register(bytes32 key, string value) {
registry[key] = value;
LogRegister(key, value);
}
function get(bytes32 key) public constant returns(string) {
return registry[key];
}
}
For contract above here is how to access it's methods:
contract.transact_and_wait.register("performer", "Beastie Boys")
Will send transaction to the blockchain and wait for it to be mined.
contract.transact.register("performer", "Black Eyed Peas")
Will send transaction to the blockchain return instantly.
contract.call.get("performer") # => "Black Eyed Peas"
Will call method of the contract and return result. Note that no transaction need to be send to the network as method is read-only. On the other hand register
method will change contract state, so you need to use transact
or transact_and_wait
to call it.
Using the example smart contract described above, one can listen for LogRegister
events by using filters.
You can get a list of events from a certain block number to the latest:
require 'ostruct'
event_abi = contract.abi.find {|a| a['name'] == 'LogRegister'}
event_inputs = event_abi['inputs'].map {|i| OpenStruct.new(i)}
decoder = Ethereum::Decoder.new
filter_id = contract.new_filter.log_register(
{
from_block: '0x0',
to_block: 'latest',
address: '0x....',
topics: []
}
)
events = contract.get_filter_logs.log_register(filter_id)
events.each do |event|
transaction_id = event[:transactionHash]
transaction = ethereum.eth_get_transaction_receipt(transaction_id)
args = decoder.decode_arguments(event_inputs, entry['data'])
puts "#{transaction.inspect} with args: #{args}"
end
By default methods interacting with contracts will use default Json RPC Client that will handle connection to ethereum node. Default client communicate via IPC. If you want to create custom client or use multiple clients you can create them yourself.
To create IPC client instance of simply create Ethereum::IpcClient:
client = Ethereum::IpcClient.new
You can also customize it with path to ipc file path and logging flag:
client = Ethereum::IpcClient.new("~/.parity/mycustom.ipc", false)
If no ipc file path given, IpcClient looks for ipc file in default locations for parity and geth. The second argument is optional. If it is true then logging is on.
By default logging is on and logs are saved in "/tmp/ethereum_ruby_http.log".
To create Http client use following:
client = Ethereum::HttpClient.new('http://localhost:8545')
You can supply client when creating a contract:
contract = Ethereum::Contract.create(client: client, ...)
You can also obtain default client:
client = Ethereum::Singleton.instance
Ethereum.rb allows you to interact directly with Ethereum node using json rpc api calls. Api calls translates directly to client methods. E.g. to call eth_gasPrice
method:
client.eth_gas_price # => {"jsonrpc"=>"2.0", "result"=>"0x4a817c800", "id"=>1}
Note: methods are translated to underscore notation using metaprogramming (See client.rb
for more information).
Full list of json rpc methods is available here
Ethereum.rb supports signing transactions with key using ruby-eth gem.
To create a new key simply do the following:
key = Eth::Key.new
Then you can use the key to deploy contracts and send transactions, i.e.:
contract = Ethereum::Contract.create(file: "...")
contract.key = key
contract.deploy_and_wait("Allo Allo!")
contract.transact_and_wait.set("greeting", "Aloha!")
You can also transfer ether transfer using custom keys:
client.transfer(key, "0x342bcf27DCB234FAb8190e53E2d949d7b2C37411", amount)
client.transfer_and_wait(key, "0x949d7b2C37411eFB763fcDCB234FAb8190e53E2d", amount)
You can change gas price or gas limit in the client:
client.gas_limit = 2_000_000_
client.gas_price = 24_000_000_000
or per contract:
contract.gas_limit = 2_000_000_
contract.gas_price = 24_000_000_000
Often in the application you want to link to blockchain explorer. This can be problematic if you want links to work with different networks (ropsten, mainnet, kovan) depending on environment you're working on. Following helpers will generate link according to network connected:
link_to_tx("See the transaction", "0x3a4e53b01274b0ca9087750d96d8ba7f5b6b27bf93ac65f3174f48174469846d")
link_to_address("See the wallet", "0xE08cdFD4a1b2Ef5c0FC193877EC6A2Bb8f8Eb373")
They use etherscan.io as a blockexplorer.
Note: Helpers work in rails environment only, works with rails 5.0+.
There are couple of rake tasks to help in wallet maintenance, i.e.:
rake ethereum:contract:deploy[path] # Compile and deploy contract
rake ethereum:contract:compile[path] # Compile a contract
rake ethereum:transaction:byhash[id] # Get info about transaction
rake ethereum:transaction:send[address,amount] # Send [amount of] ether to an account
Logs from communication between ruby app and node are available under following path:
/tmp/ethereum_ruby_http.log
Run bin/console
for an interactive prompt that will allow you to experiment.
Make sure rake ethereum:test:setup
passes before running tests.
Then, run rake spec
to run the tests.
Test that do send transactions to blockchain are marked with blockchain
tag. Good practice is to run first fast tests that use no ether and only if they pass, run slow tests that do spend ether. To do that use the following line:
$ bundle exec rspec --tag ~blockchain && bundle exec rspec --tag blockchain
You need ethereum node up and running for tests to pass and it needs to be working on testnet (Ropsten).
This library has been forked from ethereum-ruby by DigixGlobal Pte Ltd (https://dgx.io).
The gem is available as open source under the terms of the MIT License.
Download Details:
Author: EthWorks
Source Code: https://github.com/EthWorks/ethereum.rb
License: MIT license
1652174880
web3swift
web3swift is an iOS toolbelt for interaction with the Ethereum network.
:zap: Swift implementation of web3.js functionality
:thought_balloon: Interaction with remote node via JSON RPC
🔐 Local keystore management (geth
compatible)
🤖 Smart-contract ABI parsing
🔓ABI deconding (V2 is supported with return of structures from public functions. Part of 0.4.22 Solidity compiler)
🕸Ethereum Name Service (ENS) support - a secure & decentralised way to address resources both on and off the blockchain using simple, human-readable names
:arrows_counterclockwise: Smart contracts interactions (read/write)
⛩ Infura support, patial Websockets API support
⚒ Parsing TxPool content into native values (ethereum addresses and transactions) - easy to get pending transactions
🖇 Event loops functionality
📱Supports Web3View functionality (WKWebView with injected "web3" provider)
🕵️♂️ Possibility to add or remove "middleware" that intercepts, modifies and even cancel transaction workflow on stages "before assembly", "after assembly"and "before submission"
✅Literally following the standards (BIP, EIP, etc):
EIP-20 (Standart interface for tokens - ERC-20), EIP-67 (Standard URI scheme), EIP-155 (Replay attacks protection), EIP-2718 (Typed Transaction Envelope), EIP-1559 (Gas Fee market change)
🗜 Batched requests in concurrent mode
RLP encoding
Base58 encoding scheme
Formatting to and from Ethereum Units
Comprehensive Unit and Integration Test Coverage
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ sudo gem install cocoapods
To integrate web3swift into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
target '<Your Target Name>' do
use_frameworks!
pod 'web3swift'
end
Then, run the following command:
$ pod install
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate web3swift into your Xcode project using Carthage, specify it in your Cartfile
. Create an empty Cartfile with the touch command and open it:
$ touch Cartfile
$ open -a Xcode Cartfile
Add the following line to the Cartfile and save it:
github "skywinder/web3swift" "master"
Run carthage update --no-use-binaries --platform iOS
to build the framework. By default, Carthage performs checkouts and creates a new directory 'Carthage' in the same location as your Cartfile. Open this directory, go to 'Build' directory, choose iOS or macOS directory, and use the selected directory framework in your Xcode project.
Open xcode setting and add this repo as a source
In the imports section:
import web3swift
Send Ether
let value: String = "1.0" // In Ether
let walletAddress = EthereumAddress(wallet.address)! // Your wallet address
let toAddress = EthereumAddress(toAddressString)!
let contract = web3.contract(Web3.Utils.coldWalletABI, at: toAddress, abiVersion: 2)!
let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic
let tx = contract.write(
"fallback",
parameters: [AnyObject](),
extraData: Data(),
transactionOptions: options)!
Send ERC-20 Token
let web3 = Web3.InfuraMainnetWeb3()
let value: String = "1.0" // In Tokens
let walletAddress = EthereumAddress(wallet.address)! // Your wallet address
let toAddress = EthereumAddress(toAddressString)!
let erc20ContractAddress = EthereumAddress(token.address)!
let contract = web3.contract(Web3.Utils.erc20ABI, at: erc20ContractAddress, abiVersion: 2)!
let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic
let method = "transfer"
let tx = contract.write(
method,
parameters: [toAddress, amount] as [AnyObject],
extraData: Data(),
transactionOptions: options)!
Get account balance
let web3 = Web3.InfuraMainnetWeb3()
let address = EthereumAddress("<Address>")!
let balance = try web3.eth.getBalance(address: address)
let balanceString = Web3.Utils.formatToEthereumUnits(balance, toUnits: .eth, decimals: 3)
Write Transaction and call smart contract method
let web3 = Web3.InfuraMainnetWeb3()
let value: String = "0.0" // Any amount of Ether you need to send
let walletAddress = EthereumAddress(wallet.address)! // Your wallet address
let contractMethod = "SOMECONTRACTMETHOD" // Contract method you want to write
let contractABI = "..." // Contract ABI
let contractAddress = EthereumAddress(contractAddressString)!
let abiVersion = 2 // Contract ABI version
let parameters: [AnyObject] = [...]() // Parameters for contract method
let extraData: Data = Data() // Extra data for contract method
let contract = web3.contract(contractABI, at: contractAddress, abiVersion: abiVersion)!
let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic
let tx = contract.write(
contractMethod,
parameters: parameters,
extraData: extraData,
transactionOptions: options)!
func contractTransactionMethod(){
let yourCoin = self.yourbalance.text ?? "0.0" //Get token for sending
let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] //get user directory for keystore
if (FileManager.default.fileExists(atPath: userDir + "/keystore/key.json")) {
//Create Keystore
guard let manager = FilestoreWrapper.getKeystoreManager() else {
print("Manager not found ")
return
}
wethioKeystoreManager = manager
guard let urlStr = URL(string: "Your rpc url here") else { return }
guard let kManager = yourKeystoreManager else { return }
//Create Web3Provider Instance with key manager
web3ProvideInstance = Web3HttpProvider(urlStr, keystoreManager: kManager)
guard let wProvier = self.web3ProvideInstance else {return}
self.web3Instance = Web3(provider: wProvier) //Set provide instance with web3
guard let wInstance = self.web3Instance else {return}
self.receiverAddressString = self.walletAddressTF.text //get receiver address string
print("Receiver address is : ", self.receiverAddressString ?? " ")
self.etheriumAccountAddress = self.wethioKeystoreManager?.addresses.first?.address //get sender address in string
/*
convert address string into etherium addresss
*/
let senderEthAddress = EthereumAddress(self.etheriumAccountAddress ?? "")
//Run on backgrounnd tread
DispatchQueue.global(qos: .background).async {
do {
//Convert receiver address in to etherium address
let toaddress = EthereumAddress(self.receiverAddressString ?? "")
var options = Web3Options.defaultOptions() //Create web3 options
let amountDouble = BigInt((Double(yourCoin) ?? 0.1)*pow(10, 18)) //Convert amount into BIGINT
print("Total amount in double value : ", amountDouble)
var amount = BigUInt.init(amountDouble) //Convert amount in BIG UI Int
let estimateGasPrice = try wInstance.eth.getGasPrice() //estimate gas price
guard let eGasReult = self.estimatedGasResult else {
print("Unable to find gas price")
return
}
let nonce = try wInstance.eth.getTransactionCount(address: senderEthAddress) //Get nonce or transaction count
print("Is the Transaction count", nonce)
let fee = estimateGasPrice * eGasReult
/*
adding
- sender address
- Gas Result
- Gas price
- amount
*/
var sendTransactionIntermediateOptions = Web3Options.defaultOptions()
sendTransactionIntermediateOptions.from = senderEthAddress
sendTransactionIntermediateOptions.gasLimit = eGasReult
sendTransactionIntermediateOptions.gasPrice = estimateGasPrice
var tokenTransactionIntermediate: TransactionIntermediate! //Create transaction intermediate
tokenTransactionIntermediate = try wInstance.contract("Your custom contract ABI string", at: contractAddress).method("transfer", args: toaddress, amount, options: sendTransactionIntermediateOptions)
let mainTransaction = try tokenTransactionIntermediate.send(options: sendTransactionIntermediateOptions, onBlock: "latest")
print(mainTransaction.hash, "is the hash of your transaction")
}
}
}
}
You can see how to our demo project: WKWebView with injected "web3" provider:
git clone https://github.com/skywinder/web3swift.git
cd web3swift/Example/web3swiftBrowser
pod install
open ./web3swiftBrowser.xcworkspace
brew install carthage
# Available platforms: `iOS, macOS`
carthage update --platform iOS --use-xcframeworks
Command + B
carthage build --no-skip-current --platform iOS
./carthage-build.sh --platform iOS
(temp workaround, for of Carthage bug. For details please look atFor full documentation details and FAQ, please look at Documentation
If you need to find or understand an API, check Usage.md.
FAQ moved Documentation Page
Here are quick references for essential features:
If you are using this library in your project, please add a link to this repo.
Nothing makes developers happier than seeing someone else use our work and go wild with it.
Join our discord if you need a support or want to contribute to web3swift development!
Download Details:
Author: skywinder
Source Code: https://github.com/skywinder/web3swift
License: Apache-2.0 license
#blockchain #swift #solidity #ethereum #smartcontract #dapp #javascript
1652167500
Web3j is a lightweight, highly modular, reactive, type safe Java and Android library for working with Smart Contracts and integrating with clients (nodes) on the Ethereum network:
This allows you to work with the Ethereum blockchain, without the additional overhead of having to write your own integration code for the platform.
The Java and the Blockchain talk provides an overview of blockchain, Ethereum and Web3j.
It has five runtime dependencies:
It also uses JavaPoet for generating smart contract wrappers.
The simplest way to start your journey with Web3j is to create a project. We provide this functionality using the Web3j CLI. This latter can be installed as follows:
For Unix:
curl -L get.web3j.io | sh && source ~/.web3j/source.sh
For Windows, in Powershell:
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/web3j/web3j-installer/master/installer.ps1'))
Create a new project by running:
$ web3j new
Or use our Maven or Gradle plugins to generate java files from Solidity contracts.
Java:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.8.7</version>
</dependency>
Android:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.8.7-android</version>
</dependency>
Java:
implementation ('org.web3j:core:4.8.7')
Android:
implementation ('org.web3j:core:4.8.7-android')
Web3j includes integration tests for running against a live Ethereum client. If you do not have a client running, you can exclude their execution as per the below instructions.
To run a full build (excluding integration tests):
$ ./gradlew check
To run the integration tests, you will need to set up these variables in order to pull the Docker images from the Docker Hub registry:
registry.username
registry.password
Then run the following command:
$ ./gradlew -Pintegration-tests=true :integration-tests:test
If you do not want the integration test to run:
$ ./gradlew -Pintegration-tests=false :test
Check the Docker client API for more information on configuration options.
Commercial support and training is available from web3labs.com.
Download Details:
Author: web3j
Source Code: https://github.com/web3j/web3j
License: Apache-2.0 license
1652163975
In this article, we discuss the basics behind smart contracts and Ethereum, and show you how to create and test smart contracts with Solidity.
Ever since Ethereum was introduced in 2015 by Canadian-Russian programmer, Vitalik Buterin, it has brought forth new decentralized applications (dApps). However, Ethereum’s success is significantly attributed to the implementation of smart contracts.
Many people believe that smart contracts are a new concept and have been invented with the Ethereum Blockchain Platform. However, they date back to 1996 when computer scientist, Nick Szabo, coined the term and defined them as:
I call these new contracts “smart”, because they are far more functional than their inanimate paper-based ancestors. No use of artificial intelligence is implied. A smart contract is a set of promises, specified in digital form, including protocols within which the parties perform on these promises.
His work later inspired other scientists and researchers, including Vitalik. Before we go deeper into the creation and deployment of an Ethereum smart contract, it is essential to understand the Ethereum Virtual Machine and Gas.
Ethereum Virtual Machine (EVM)
The purpose of EVM is to serve as a runtime environment for smart contracts built on Ethereum. Consider it as a global supercomputer that executes all the smart contracts.
As the name indicates, Ethereum Virtual Machine is not physical, but a virtual machine.
Gas
In the Ethereum Virtual Machine, Gas is a measurement unit used for assigning fees to each transaction with a smart contract. Each computation happening in the EVM needs some amount of gas. The more complex the computation is, the more the gas is required to run the smart contracts.
Transaction fee = Total gas used*gas price
Let’s understand what is a smart contract and how it works.
Smart Contracts are the business logic or a protocol according to which all the transactions on a Blockchain happen. The general objective of the smart contract is to satisfy common contractual conditions. For example, if we want to create our own token on Ethereum, we need to develop smart contracts according to which all the calculations on our token would happen.
It is a stand-alone script written in Solidity, compiled into JSON, and deployed to a particular address on the blockchain. Just like we can call a URL endpoint of a RESTful API to run some logic through an HttpRequest, we can execute a deployed smart contract similarly at a particular address by entering accurate data along with Ethereum to call the compiled and deployed Solidity function.
Smart contracts can be deployed to the decentralized database for a fee proportional to the storage size of the containing code. It can be also be defined as a collection of code stored in the blockchain network, defining conditions to which all parties within the contract should agree upon.
We will be sharing an example of an Ethereum smart contract using the Solidity programming language. So, it is first essential to understand what is Solidity.
Solidity is a JavaScript-like language developed specifically for creating smart contracts. It is typed statically and supports libraries, inheritance, and complex user-defined types.
Solidity compiler converts code into EVM bytecode, which is sent to the Ethereum network as a deployment transaction. Such transactions have more fees compared to smart contract interactions, and the owner of the contract must pay them.
MetaMask acts both as an Ethereum browser and a wallet. It allows you to interact with smart contracts and dApps on the web without downloading the blockchain or installing any software. You only need to add MetaMask as a Chrome Extension, create a wallet, and submit Ether.
Though MetaMask is currently available for Google Chrome browser, it is expected to launch for Firefox too in the coming years.
Download the MetaMask Chrome extension before you start writing smart contracts.
Once it is downloaded and added as a Chrome extension, you can either import an already created wallet or create a new wallet. You must have some amount of Ethers in your Ethereum wallet to deploy an Ethereum smart contract on the network.
Install MetaMask in your Chrome browser and enable it. Once it is installed, click on its icon on the top right of the browser page. Clicking on it will open it in a new tab of the browser.
Click on Create Wallet and agree to the terms and conditions by clicking I agree to proceed further. It will ask you to create a password.
After you create a password, it will send you a secret backup phrase that can be used for backing up and restoring the account. Do not disclose it or share it with someone, as this phrase can take away your Ethers.
Next, ensure that you are in the Main Ethereum Network. If you find a checkmark next to “Main Ethereum Network, you are in the right place.
You might also find the following test networks in your MetaMask wallet:
The above networks are for testing purposes only; note that the Ethers of these networks have no real value.
In case you want to test the smart contract, you must have some dummy Ethers in your MetaMask wallet.
For example, if you want to test a contract using the Robsten test network, select it, and you will find 0 ETH as the initial balance in your account.
To add dummy Ethers, click on the Deposit and Get Ether button under Test Faucet.
To proceed, you need to click request 1 ether from faucet and one ETH will be added to your wallet. You can add as many Ethers as you want in the test network.
For example, I have added one ETH in this scenario.
Once the dummy Ethers are added to the wallet, you can start writing smart contracts on the Remix Browser IDE in Solidity.
We will use Remix Browser IDE to write our Solidity code. Remix is the best option for writing smart contracts, as it comes with a handful of features and offers comprehensive development experience.
It is usually used for writing smaller sized contracts. Remix’s features include:
Let’s start writing smart contract code by going here.
Open Remix Browser, and click on the plus icon on the top left side next to the browser to create a .sol extension file.
ERC20.sol is a standard template for ERC20 tokens.
pragma solidity ^0.4.0;
import "./ERC20.sol";
contract myToken is ERC20{
mapping(address =>uint256) public amount;
uint256 totalAmount;
string tokenName;
string tokenSymbol;
uint256 decimal;
constructor() public{
totalAmount = 10000 * 10**18;
amount[msg.sender]=totalAmount;
tokenName="Mytoken";
tokenSymbol="Mytoken";
decimal=18;
}
function totalSupply() public view returns(uint256){
return totalAmount;
}
function balanceOf(address to_who) public view
returns(uint256){
return amount[to_who];
}
function transfer(address to_a,uint256 _value) public
returns(bool){
require(_value<=amount[msg.sender]);
amount[msg.sender]=amount[msg.sender]-_value;
amount[to_a]=amount[to_a]+_value;
return true;
}
}
Select a version of the compiler from Remix to compile the solidity Ethereum smart contract code.
Deploy the smart contract at the Ethereum test network by pressing the deploy button at the right-hand side of the Remix window. Wait until the transaction is complete.
After the transaction commits successfully, the address of the smart contract would be visible at the right-hand side of the Remix window. At first, all the ERC20 token will be stored in the wallet of the user who is deploying the smart contract.
To check the tokens in your wallet, go to the MetaMask window, click add tokens, enter the smart contract address, and click ok. You should be able to see the number of tokens there.
You can now run your smart contract methods at Etherscan.
Original article source at https://www.leewayhertz.com
#ethereum #smartcontracts #solidity #blockchain
1652160180
is a typed PHP-7.1+ interface to Ethereum JSON-RPC API.
Check out the latest API documentation.
{
"minimum-stability":"dev",
"autoload": {
"psr-4": {
"Ethereum\\": "src/"
}
},
"repositories": [
{
"type": "git",
"url": "https://github.com/digitaldonkey/ethereum-php.git"
}
],
"require": {
"digitaldonkey/ethereum-php": "dev-master"
}
}
composer require digitaldonkey/ethereum-php
This is the important part of composer.json in Drupal Ethereum Module.
require __DIR__ . '/vendor/autoload.php';
use Ethereum\Ethereum;
try {
// Connect to Ganache
$eth = new Ethereum('http://127.0.0.1:7545');
// Should return Int 63
echo $eth->eth_protocolVersion()->val();
}
catch (\Exception $exception) {
die ("Unable to connect.");
}
Calling Contracts
You can call (unpayed) functions in smart contracts easily.
The json file "$fileName" used is what you get when you compile a contract with Truffle.
$ContractMeta = json_decode(file_get_contents($fileName));
$contract = new SmartContract(
$ContractMeta->abi,
$ContractMeta->networks->{NETWORK_ID}->address,
new Ethereum(SERVER_URL)
);
$someBytes = new EthBytes('34537ce3a455db6b')
$x = $contract->myContractMethod();
echo $x->val()
You can also run tests at smart contracts, check out EthTestClient.
You can use Ethereum-PHP to watch changed on your smart contracts or index a Blockchain block by block. gs
See UsingFilters and ethereum-php-eventlistener.
Currently not all datatypes are supported.
This library is read-only for now. This means you can retrieve information stored in Ethereum Blockchain.
To write to the blockchain you need a to sign transactions with a private key which is not supported yet.
The API documentation is available at ethereum-php.org.
For reference see the Ethereum RPC documentation and for data encoding RLP dcumentation in Ethereum Wiki.
There is also a more readable Ethereum Frontier Guide version.
Download Details:
Author: digitaldonkey
Source Code: https://github.com/digitaldonkey/ethereum-php
License: MIT license
#blockchain #php #solidity #solidity #ethereum #smartcontract
1652152860
A php interface for interacting with the Ethereum blockchain and ecosystem.
Set minimum stability to dev
"minimum-stability": "dev"
Then
composer require sc0vu/web3.php dev-master
Or you can add this line in composer.json
"sc0vu/web3.php": "dev-master"
use Web3\Web3;
$web3 = new Web3('http://localhost:8545');
use Web3\Web3;
use Web3\Providers\HttpProvider;
use Web3\RequestManagers\HttpRequestManager;
$web3 = new Web3(new HttpProvider(new HttpRequestManager('http://localhost:8545')));
// timeout
$web3 = new Web3(new HttpProvider(new HttpRequestManager('http://localhost:8545', 0.1)));
$web3->clientVersion(function ($err, $version) {
if ($err !== null) {
// do something
return;
}
if (isset($version)) {
echo 'Client version: ' . $version;
}
});
use Web3\Web3;
$web3 = new Web3('http://localhost:8545');
$eth = $web3->eth;
Or
use Web3\Eth;
$eth = new Eth('http://localhost:8545');
use Web3\Web3;
$web3 = new Web3('http://localhost:8545');
$net = $web3->net;
Or
use Web3\Net;
$net = new Net('http://localhost:8545');
web3
$web3->batch(true);
$web3->clientVersion();
$web3->hash('0x1234');
$web3->execute(function ($err, $data) {
if ($err !== null) {
// do something
// it may throw exception or array of exception depends on error type
// connection error: throw exception
// json rpc error: array of exception
return;
}
// do something
});
eth
$eth->batch(true);
$eth->protocolVersion();
$eth->syncing();
$eth->provider->execute(function ($err, $data) {
if ($err !== null) {
// do something
return;
}
// do something
});
net
$net->batch(true);
$net->version();
$net->listening();
$net->provider->execute(function ($err, $data) {
if ($err !== null) {
// do something
return;
}
// do something
});
personal
$personal->batch(true);
$personal->listAccounts();
$personal->newAccount('123456');
$personal->provider->execute(function ($err, $data) {
if ($err !== null) {
// do something
return;
}
// do something
});
use Web3\Contract;
$contract = new Contract('http://localhost:8545', $abi);
// deploy contract
$contract->bytecode($bytecode)->new($params, $callback);
// call contract function
$contract->at($contractAddress)->call($functionName, $params, $callback);
// change function state
$contract->at($contractAddress)->send($functionName, $params, $callback);
// estimate deploy contract gas
$contract->bytecode($bytecode)->estimateGas($params, $callback);
// estimate function gas
$contract->at($contractAddress)->estimateGas($functionName, $params, $callback);
// get constructor data
$constructorData = $contract->bytecode($bytecode)->getData($params);
// get function data
$functionData = $contract->at($contractAddress)->getData($functionName, $params);
Due to callback is not like javascript callback, if we need to assign value to outside scope, we need to assign reference to callback.
$newAccount = '';
$web3->personal->newAccount('123456', function ($err, $account) use (&$newAccount) {
if ($err !== null) {
echo 'Error: ' . $err->getMessage();
return;
}
$newAccount = $account;
echo 'New account: ' . $account . PHP_EOL;
});
To run examples, you need to run ethereum blockchain local (testrpc).
If you are using docker as development machain, you can try ethdock to run local ethereum blockchain, just simply run docker-compose up -d testrpc
and expose the 8545
port.
git clone https://github.com/sc0Vu/web3.php.git && cd web3.php && composer install
2. Run test script.
vendor/bin/phpunit
git clone https://github.com/sc0Vu/web3.php.git
2. Copy web3.php to web3.php/docker/app directory and start container.
cp files docker/app && docker-compose up -d php ganache
3. Enter php container and install packages.
docker-compose exec php ash
4. Change testHost in TestCase.php
/**
* testHost
*
* @var string
*/
protected $testHost = 'http://ganache:8545';
5. Run test script
vendor/bin/phpunit
Install packages
Enter container first
docker-compose exec php ash
6. gmp
apk add gmp-dev
docker-php-ext-install gmp
7. bcmath
docker-php-ext-install bcmath
Remove extension
Move the extension config from /usr/local/etc/php/conf.d/
mv /usr/local/etc/php/conf.d/extension-config-name to/directory
API
Todo.
Download Details:
Author: sc0Vu
Source Code: https://github.com/sc0Vu/web3.php
License: MIT license
1652145360
A Python library for interacting with Ethereum, inspired by web3.js.
Get started in 5 minutes or take a tour of the library.
For additional guides, examples, and APIs, see the documentation.
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for contributing, then check out issues that are labeled Good First Issue.
Download Details:
Author: ethereum
Source Code: https://github.com/ethereum/web3.py
License: MIT license
#blockchain #python #web3 #solidity #ethereum #smartcontract
1652130780
A Purescript Client for the Web3 API
purescript-web3
is a library for interacting with an ethereum node purescript. At the moment it covers most endpoints of the web3 api, which means it is suitable for sending transactions, querying blockchain state and metadata, and monitoring events.
Using purescript-web3-generator it is also possible (and recommended) to generate a library from a set of smart contract abis which is capable of templating transactions and event filters/watchers. The README has instructions for getting started.
We do not yet have a build tool similar to truffle, but if you are looking for a template of how to use truffle and write your tests using purescript, check out out the purescript-web3-tests
To see an example project using all of the purescript-web3 tools and with thermite/react ui, check out purescript-web3-example.
> npm install
> npm run build
> npm run test
Module documentation is published on Pursuit.
Suppose we have the following solidity smart contract:
contract TupleStorage {
uint x;
uint y;
event TupleSet(uint newX, uint newY);
function setTuple(uint _x, uint _y) public {
x = _x;
y = _y;
TupleSet(_x, _y);
}
}
If we used purescript-web3-generator, we are given a function with the following signature:
setTuple :: forall e.
TransactionOptions NoPay
-> {_x :: UIntN (D2 :& D5 :& DOne D6), _y :: UIntN (D2 :& D5 :& DOne D6)}
-> Web3 HexString
It's pretty clear what this function is doing, but let's look at the TransactionOptions
. This record keeps track of, for example, who is the transaction from, what contract address is it going to, is there ether being sent, etc. In this case, the function is not "payable", so this is indicated in the type of the TransactionOptions
. It is set using lenses like:
setTupleOpts :: TransactionOptions NoPay
setTupleOpts = defaultTransactionOptions
# _from ?~ myAddress
# _to ?~ tupleStorageAddress
Now for the TupleSet
event. In order to start an event watcher, we need to establish the Filter
, which specifies things like the range of blocks we are interested in, and how to find that particular contract and topic. Again, if you're using web3-generator, things are a lot simpler:
tupleFilter :: Filter TupleSet
tupleFilter = eventFilter (Proxy :: Proxy TupleSet) tupleStorageAddress
# _fromBlock .~ BN 100
We also need to pass a callback to the event watcher that performs some action and decides whether or not to unregister the filter. For example, we could set up an event monitor starting from block 100 and continuing until the two coordinates that are set are equal:
event tupleFilter $ \(TupleSet {newX,newY} -> do
liftAff <<< log $ "Received New Tuple : " <> show (Tuple newX newY)
if newX == newY
then pure TerminateEvent
else do
_ <- performAction newX newY
pure ContinueEvent
For more examples, check out the foam kitty monitor, the example project using thermite, or the purescript-web3-tests repo.
Download Details:
Author: f-o-a-m
Source Code: https://github.com/f-o-a-m/purescript-web3
License: Apache-2.0 license