Git Product home page Git Product logo

web3.zig's Introduction

web3.zig

A collection of utilities for interacting with a local or remote ethereum node. Similar to the javascript frameworks web3.js or ethers.js.

No external dependencies aside from "std".

This library is currently incomplete and probably not suitable for production use.

Implementation Roadmap

This is a list of what has been implemented and what is planned.

Json RPC

method implementation status
web3_clientVersion
web3_sha3
net_version
net_listening
net_peerCount
eth_protocolVersion
eth_syncing
eth_coinbase
eth_chainId
eth_mining
eth_hashrate
eth_gasPrice
eth_accounts
eth_blockNumber
eth_feeHistory
eth_getBalance
eth_getStorageAt
eth_getTransactionCount
eth_getBlockTransactionCountByHash
eth_getBlockTransactionCountByNumber
eth_getUncleCountByBlockHash
eth_getUngleCountByBlockNumber
eth_getCode
eth_sign
eth_signTransaction
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_newFilter
eth_newBlockFilter
eth_newPendingTransactionFilter
eth_uninstallFilter
eth_getFilterChanges
eth_getFilterLogs
eth_getLogs

Transports

  • ✅ HTTP
  • ❌ WebSocket
  • ❌ IPC

ABI Types

  • ✅ uint<M>
  • ✅ int<M>
  • ✅ address
  • ✅ bool
  • ✅ <type>[M]
  • ✅ <type>[]
  • ✅ string
  • ❌ fixed<M>x<N>
  • ❌ ufixed<M>x<N>
  • ✅ function
  • ✅ bytes<M>
  • ✅ bytes
  • ✅ (T1,T2,...,Tn) (aka tuples/structs)

Features

  • ✅ JSON RPC communication
  • ✅ ABI encoding/decoding
  • ✅ ABI parsing (JSON)
  • ✅ Abstracted contract interaction (partially implemented)
  • ❌ Async support (not available in Zig 0.11.0 anyway)
  • ✅ Local account features (signing transactions, HD wallets, etc.)
  • ❌ Log and transaction filters
  • ❌ Abstracted contract deployment
  • ✅ RLP/transaction encoding
  • ❌ RLP decoding
  • ❌ Native ENS support
  • ❌ Documentation
  • ❌ Comprehensive tests

License

MIT - Copyright (c) 2023, Kane Wallmann

Installation

This library exports a module that can be included in your project via Zig's package manager.

Add it as a dependency to your build.zig.zon like so:

...
    .dependencies = .{
        .web3 = .{
            .url = "https://github.com/kanewallmann/web3.zig/archive/refs/heads/master.tar.gz",
        },
    },
...

In your build.zig file add the module to your build by adding the lines:

    const web3 = b.dependency("web3", .{ .target = target, .optimize = optimize });
    exe.addModule("web3", web3.module("web3"));

Then run zig build.

Zig will complain about the hash being incorrect:

note: expected .hash = "12201309cabc8d4c7d5482c7f19754f1f7f779e3cae525a4e6c9ea0e0a824a0bfe69",

Copy that into your build.zig.zon file like so:

...
    .dependencies = .{
        .web3 = .{
            .url = "https://github.com/kanewallmann/web3.zig/archive/refs/heads/master.tar.gz",
            .hash = "12201309cabc8d4c7d5482c7f19754f1f7f779e3cae525a4e6c9ea0e0a824a0bfe69",
        },
    },
...

And then you are ready to @import("web3") in your project.

Examples

There are a few examples under src/examples. They can be run with zig build example_{example_name} -- {rpc_endpoint} where {example_name} is the name of one of the examples and {rpc_endpoint} is an RPC endpoint URI. (Currently only HTTP transport is implemented)

Example:

zig build example_erc20 -- http://localhost:8545

web3.zig's People

Contributors

kanewallmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

web3.zig's Issues

Example of how to make a signed call?

Hello, first of all, thank you for the previous answer, it was enlightening, I already made the necessary adjustments, but now I have another question so I decided to open this new issue to explain it better.
Well I have a simple smart contract that I am testing. This contract is simply used to store and retrieve information, here it is:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.2;

contract Messenger {
    address _commander;

    bytes32 _ApiHash;
    string _ConfApiJson;

    constructor(address owner) {
        _commander = owner;
    }
    // Set
    function setApi(string memory value) public returns (bytes32) {
        require(msg.sender == _commander);
        
        _ConfApiJson = value;
        _ApiHash = keccak256(abi.encode(value,200));
        return _ApiHash;
    }
    // Get
    function getApi() public view returns (string memory) {
        return(_ConfApiJson);
    }
    // Get 'hash' of last message
    function getApiHash() public view returns (bytes32) {
        return(_ApiHash);
    }
} 

As you can see, the setApi function receives a string and returns bytes32 which is the hash of the saved value, as you can also see, only the owner of the contract can send new messages, so I have to make a signed call, Below is an implementation that I made but for some reason that I still don't know, it didn't generate a transaction on the blockchain:

const Messenger = struct {
    const Self = @This();

    contract: web3.ContractCaller,

    pub fn init(allocator: std.mem.Allocator, address: web3.Address, provider: web3.Provider) Messenger {
        return Messenger{
            .contract = web3.ContractCaller.init(
                allocator,
                address,
                provider,
            ),
        };
    }

    pub fn setApi(self: Self, message: []const u8, opts: web3.CallOptions) !web3.Bytes(32) {
        const selector = comptime try web3.abi.computeSelectorFromSig("setApi(string)");

        return try self.contract.callSelector(selector, .{message}, web3.Bytes(32), opts);
    }

    pub fn getApi(self: Self, opts: web3.CallOptions) []const u8 {
        const selector = comptime try web3.abi.computeSelectorFromSig("getApi()");
        return self.contract.callSelector(selector, .{}, []const u8, opts) catch unreachable;
    }

    pub fn getApiHash(self: Self, opts: web3.CallOptions) !web3.Bytes(32) {
        const selector = comptime try web3.abi.computeSelectorFromSig("getApiHash()");
        return try self.contract.callSelector(selector, .{}, web3.Bytes(32), opts);
    }
};

pub fn setApiValue(
    allocator: std.mem.Allocator,
    rpc: []const u8,
    contractAddress: []const u8,
    privKey: []const u8,
    msgStr: []const u8,
) !web3.Bytes(32) {
    const contract_addr = try web3.Address.fromString(contractAddress);

    var json_rpc_provider = try web3.JsonRpcProvider.init(allocator, try std.Uri.parse(rpc));
    defer json_rpc_provider.deinit();

    var signer = try web3.LocalSigner.fromString(allocator, privKey, .{});

    var signing_provider = web3.SigningProvider.init(allocator, signer.signer(), json_rpc_provider.provider());

    // Create messenger instance
    var messenger = Messenger.init(allocator, contract_addr, signing_provider.provider());

    // Call setApi
    const call_set_api: web3.Bytes(32) = try messenger.setApi(msgStr, .{});

    return call_set_api;
}

Usage:

// ...
 
 const hash = try app.setApiValue(
    allocator,
    "https://rpc-mainnet.maticvigil.com/",  // Polygon MainNet
    contract, // Contract Address
    "3fc1...3681",    // PrivKey
    "Hello from Zig",  // Msg
);
std.log.info("ApiHash => '{any}'", .{hash.raw});

// ... 

Output:

Cmd: getapi
info: Value => http://localhost:5000 <-- This is an old message saved in the contract.
Cmd: setapi
info: ApiHash => '{ 209, 214, 32, 183, 70, 247, 212, 131, 45, 11, 115, 101, 209, 235, 153, 131, 241, 226, 28, 186, 197, 118, 67, 205, 140, 212, 109, 75, 232, 42, 240, 206 }'
Cmd: getapi
info: Value => http://localhost:5000 <-- Nothing changed

As you can see, bytes32 was returned, but no signed transactions have been created on the polygon blockchain, could you give me a more detailed example of how I can do this?

Thanks.

Memory Leak error in decodeArg

Hi, I have the following code below based on the examples provided that when finishing the application causes memoryleak:

pub fn getApiValue(allocator: std.mem.Allocator, rpc: []const u8, contractAddress: []const u8) !void {
    var json_rpc_provider = try web3.JsonRpcProvider.init(allocator, try std.Uri.parse(rpc));
    defer json_rpc_provider.deinit();

    const contract_addr = web3.Address.fromString(contractAddress) catch unreachable;

    // Create messenger instance
    var messenger = Messenger.init(allocator, contract_addr, json_rpc_provider.provider());

    // Call getApi
    const call_api = messenger.getApi(.{});

    std.log.info("getApi => {s}", .{call_api});

    // Call getApiHash
    const call_hash: web3.Bytes(32) = try messenger.getApiHash(.{});

    std.log.info("getHash => {any}", .{call_hash.raw});
}

const Messenger = struct {
    const Self = @This();

    contract: web3.ContractCaller,

    pub fn init(allocator: std.mem.Allocator, address: web3.Address, provider: web3.Provider) Messenger {
        return Messenger{
            .contract = web3.ContractCaller.init(
                allocator,
                address,
                provider,
            ),
        };
    }
    pub fn getApi(self: Self, opts: web3.CallOptions) []const u8 {
        const selector = comptime try web3.abi.computeSelectorFromSig("getApi()");
        var result = self.contract.callSelector(selector, .{}, []const u8, opts) catch unreachable;
        return result;
    }

    pub fn getApiHash(self: Self, opts: web3.CallOptions) !web3.Bytes(32) {
        const selector = comptime try web3.abi.computeSelectorFromSig("getApiHash()");
        return try self.contract.callSelector(selector, .{}, web3.Bytes(32), opts);
    }
};

GPA Output:

error(gpa): memory address 0x1d737930000 leaked: 
C:\Users\Root\AppData\Local\zig\p\1220e42c078ae1683bf33b5e453994f64120ae58c499eff8fa39e80d4b64e4912c22\src\abi.zig:731:47: 0x7ff6f11c7e77 in decodeArg__anon_12264 (zcc.exe.obj)
            var str_copy = try allocator.alloc(u8, str_len);
                                              ^
C:\Users\Root\AppData\Local\zig\p\1220e42c078ae1683bf33b5e453994f64120ae58c499eff8fa39e80d4b64e4912c22\src\contract.zig:156:34: 0x7ff6f11c7978 in callSelector__anon_12263 (zcc.exe.obj)
        return web3.abi.decodeArg(self.allocator, result, 0, T);
                                 ^
F:\sources\zcc\src\app.zig:145:48: 0x7ff6f11a83db in getApi (zcc.exe.obj)
        var result = self.contract.callSelector(selector, .{}, []const u8, opts) catch unreachable;
                                               ^
F:\sources\zcc\src\app.zig:119:38: 0x7ff6f11a81b4 in getApiValue (zcc.exe.obj)
    const call_api = messenger.getApi(.{});
                                     ^

Any tips to solve the problem would be welcome, Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.