Coder Social home page Coder Social logo

abieos's Introduction

abieos

Binary <> JSON conversion using ABIs. Compatible with languages which can interface to C; see src/abieos.h.

Alpha release. Feedback requested.

Packing transactions

  1. Create a context: abieos_create
  2. Use abieos_set_abi to load eosjs2/src/transaction.abi into contract 0.
  3. Use abieos_set_abi to load the contract's ABI.
  4. Use abieos_json_to_bin and abieos_get_bin_hex to convert action data to hex. Use abieos_get_type_for_action to get the action's type.
  5. Use abieos_json_to_bin and abieos_get_bin_hex to convert transaction to hex. Use contract = 0 and type = abieos_string_to_name(context, "transaction").
  6. Destroy the context: abieos_destroy

Usage note

abieos expects object attributes to be in order. It will complain about missing attributes if they are out of order.

Example data

Example action data for abieos_json_to_bin:

{
    "from": "useraaaaaaaa",
    "to": "useraaaaaaab",
    "quantity": "0.0001 SYS",
    "memo": ""
}

Example transaction data for abieos_json_to_bin:

{
    "expiration": "2018-06-27T20:33:54.000",
    "ref_block_num": 45323,
    "ref_block_prefix": 2628749070,
    "max_net_usage_words": 0,
    "max_cpu_usage_ms": 0,
    "delay_sec": 0,
    "context_free_actions": [],
    "actions": [{
        "account": "eosio.token",
        "name": "transfer",
        "authorization":[{
            "actor":"useraaaaaaaa",
            "permission":"active"
        }],
        "data":"608C31C6187315D6708C31C6187315D60100000000000000045359530000000000"
    }],
    "transaction_extensions":[]
}

Ubuntu 16.04 with gcc 8.1.0

  • Install these. You may have to build them yourself from source or find a PPA. Make them the default.
    • gcc 8.1.0
    • cmake 3.11.3
  • sudo apt install libboost-dev libboost-date-time-dev
  • remove this from CMakeLists.txt (2 places): -fsanitize=address,undefined
mkdir build
cd build
cmake ..
make
./test

License

MIT

abieos's People

Contributors

allenhan2 avatar arhag avatar b1bart avatar brianjohnson5972 avatar bytemaster avatar cc32d9 avatar cj-oci avatar dependabot[bot] avatar dimas1185 avatar emorybarlow avatar greg7mdp avatar heifner avatar huangminghuang avatar igorls avatar jeffreyssmith2nd avatar jgiszczak avatar josephjguerra avatar larryk85 avatar leordev avatar linh2931 avatar nksanthosh avatar spoonincode avatar swatanabe-b1 avatar tbfleming avatar tedcahalleos avatar venu-block1 avatar victorj8 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abieos's Issues

json conversion of some float64 values seems less precise than expected

Consider the following which uses the fpconv_dtoa() function as used by abieos' bin->json conversion,

int main() {
	double x = 151115727451828646838272.0;
	std::cout << std::to_string(x) << std::endl;

	char buf[26] = {};
        fpconv_dtoa(x, buf);
	std::cout << buf << std::endl;
	return 0;
}

The output is,

151115727451828646838272.000000
151115727451828650000000

This value is 2^77 and should be perfectly representable in a double -- and std::to_string() clearly shows it as being so. But when fpconv_dtoa() prints it some precision is lost.

empty floating point value

I'm troubleshooting a strange problem with Chronicle and a recent WAX snapshot. While processing table deltas from the initial block in the state history, abieos_bin_to_json generated invalid JSON on one particular table row:

Contract: eosio
Table: voters
Scope: eosio
primary_key: "4855417838370997808"

Value:
{"owner":"chkyln44af33","proxy":"hodlwaxiopro","producers":[],"staked":"107200000","unpaid_voteshare":0,"unpaid_voteshare_last_updated":"2023-11-27T03:55:55.000","unpaid_voteshare_change_rate":5.84764897204348e+36,"last_claim_time":"2023-11-27T03:55:55.000","last_vote_weight":5.847648972043329e+36,"proxied_vote_weight":,"is_proxy":false,"flags1":0,"reserved2":0,"reserved3":"0 "}

The float64 in proxied_vote_weight is represented by an empty string, which breaks the resulting JSON syntax.

The table row in question (nodeos version 3.2.3wax01):

cleos -u https://wax.eu.eosamsterdam.net get table eosio eosio voters -L 4855417838370997808 -l 1
{
  "rows": [{
      "owner": "chkyln44af33",
      "proxy": "hodlwaxiopro",
      "producers": [],
      "staked": 107200000,
      "unpaid_voteshare": "0.00000000000000000",
      "unpaid_voteshare_last_updated": "2023-11-27T03:55:55.000",
      "unpaid_voteshare_change_rate": "5847648972043480480643942873884000256.00000000000000000",
      "last_claim_time": "2023-11-27T03:55:55.000",
      "last_vote_weight": "5847648972043329364916491045237161984.00000000000000000",
      "proxied_vote_weight": "-151115727451828646838272.00000000000000000",
      "is_proxy": 0,
      "flags1": 0,
      "reserved2": 0,
      "reserved3": "0 "
    }
  ],
  "more": true,
  "next_key": "4855443352568570880"
}

I looked through the sources of include/eosio/to_json.hpp and include/eosio/fpconv.c, but couldn't find a condition which would result in empty string.

abieos_bin_to_json fails on trailing zeros

seen in abieos as of July 5th 2022:

transfer action arguments have extra trailing zeros, like following:

90af61cc64aca479 000000000000ba4a 02b0d00300000000 06584d4400000000 00000000
90af61cc64aca479 000000000000ba4a 4e94d00300000000 06584d4400000000 00000000

instead of last 4 zero bytes, one (?) byte should indicate an empty memo, and the rest is garbage that should be ignored. But abieos_bin_to_json fails to decode this.

"Invalid nesting" error when trying to use an optional vector in ABI

I've got an EOS smart contract which uses std::optional<std::vector<eosio::name>> as a type of one of its fields. When compiled with AntelopeIO CDT v4.0.1, it produces an ABI which seems to be valid and works fine when deployed to blockchain. However, the abieos lib fails to parse the ABI and throws an "Invalid nesting" error.

Here is a minimum reproducible code to illustrate the problem:

#include <abieos.h>
#include <iostream>

int main( int argc, char** argv ) {
    const char *bad_abi = R"(
    {
      "version": "eosio::abi/1.2",
      "types": [{
          "new_type_name": "B_vector_name_E",
          "type": "name[]"
        }
      ],
      "structs": [{
          "name": "actionname",
          "base": "",
          "fields": [{
              "name": "opt_list",
              "type": "B_vector_name_E?"
            }
          ]
        }
      ],
      "actions": [{
          "name": "actionname",
          "type": "actionname",
          "ricardian_contract": ""
        }
      ],
      "ricardian_clauses": [],
      "error_messages": [],
      "abi_extensions": [],
      "variants": [],
      "action_results": []
    }
    )";

    auto context = abieos_create ();
    if (abieos_set_abi (context, 1, bad_abi)) {
        std::cout << "OK";
    } else {
        std::cout << abieos_get_error (context); // getting "Invalid nesting" here
    }

    return 0;
}

Considering this ABI is valid, would be nice to add support of such nested structures to the lib :)

consider undoing murmur hash of invalid name when reading name from JSON

When reading a name from JSON,

template <typename S>
void from_json(name& obj, S& stream) {
auto r = stream.get_string();
obj = name(hash_name(r));
}

abieos first checks if it's a valid name and uses it, but if it's not a valid name it makes it a valid name by murmur hashing it,
inline constexpr uint64_t hash_name( std::string_view str ) {
auto r = try_string_to_name_strict(str);
if( r ) return r.value();
return murmur64( str.data(), str.size() );
}

This yields (imo) surprising behavior for someone using abieos to serialize actions from JSON. For example, someone using abieos' JSON->bin serialization may pass abieos

{"from":"bob bob bob","to":"carol","quantity":"2.0000 EOS","memo":"sup"}

what would you expect to happen here? nodeos will disallow serialization in this case because bob bob bob isn't a valid name. but abieos will serialize it, with from being the murmur hash output of bob bob bob. I consider nodeos the canonical abi behavior and abieos should match it.

Multiplatform and Multi-language Support

Work Title

Create Typescript implementation of wire protocol. Shippable as a separate package.

Requirements

Create well structured wire interface to enable serialization and deserialization. This can then be used for multi-language support and multi-platform support. Create wrappers for language support in Javascript, Go, Flutter, Swift, and Rust.

Should be significantly faster compared to JS and TS implementations.

Scenarios

Two big scenarios here.

  • Easy to support multiple languages and platforms.
    • Support for mobile devices and their languages
    • Support for other languages like Go, Flutter, Swift, and Rust
  • Backend services needs to fwd a transaction to a mobile device to sign
    • Must deserialize account to understand where to send transaction
    • Might need to pull out action information

Additional Considerations

Design Notes

Consider taking eosio-core and separating out functionality that would work for backend services. It pretty much already does this, so we may consider this scenario solved.

Leverage C-code ABIEOS and connect to different platforms

Coding Notes

How to code it

Additional context

Add any other context about the problem here.

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.