Contract call returns error "Found input with 28 bits, expected 8". Polkadot.js and ink contracts - smartcontracts

as the title suggest, Im trying to call PSP22 token contract and read balanceOf() function, but i get error that im passing a too big of a input (27 instead of 8)
Im trying to invoke balanceOf() PSP22 ink! contract.
When i initializing the token it works correctly and i can see the abi:
alanceOf: function createQuery(origin, options)
​​​​​
length: 2
​​​​​
meta: Object { isMutating: false, isPayable: false, identifier: "balance_of", … }
​​​​​​
args: Array [ {…} ]
​​​​​​​
0: Object { name: "owner", type: {…} }
​​​​​​​​
name: "owner"
​​​​​​​​
type: Object { info: 10, type: "AccountId" }
Here is the code:
const tokenContract = new ContractPromise(api, abiToken, "5FmJDyLBoYKfiaoPUcfR3WKh13HkwvXr2CYTNg5RLykNXY3A");
dispatch(set_token_contract(tokenContract));
const value = 0; // only useful on isPayable messages
// NOTE the apps UI specified these in mega units
const gasLimit = 3000n * 1000000n;
// (We perform the send from an account, here using Alice's address)
let alice = "5DaYseV9GSrGKrJYmKU5yymF9izPM2ZzG8f93xQK6hectHuo"
const { gasConsumed, result, output } = await tokenContract.query.balanceOf(alice, { gasLimit }alice);
here is the error:
RPC-CORE: call(callRequest: ContractCallRequest, at?: BlockHash): ContractExecResult:: createType(ContractExecResult):: Struct: failed on result: {"_enum":{"Ok":"ContractExecResultOk","Err":"ContractExecResultErr"}}:: Enum(Err):: Enum(Module):: Struct: failed on error: u8:: u8: Input too large. Found input with 28 bits, expected 8

Related

Return custom Error in Union Graphql Type while show list data | returning list with union type in graphql [duplicate]

This question already has answers here:
GraphQL Expected Iterable, but did not find one for field xxx.yyy
(10 answers)
Closed 2 years ago.
I'm using Apollo server for my project returning list(array) of data when I try to return Error union type it shows this error:
"errors": [
{
"message": "Expected Iterable, but did not find one for field \"Query.getReports\".",
My Schema:
type Query {
getReports(id: ID!, patient_id: Int): [getReportUnion]!
}
union getReportUnion = Error | getReportResult
type getReportResult {
id: ID!
patient_id: Int!
}
type Error {
error: Boolean!
message: String!
}
my Resolver:
getReports: async (parent: any, args: any, context: any, info: any) => {
/**
* Simplify
*/
const { id, patient_id } = args;
const { isAuth, userId } = context.Auth;
/**
* Authenticating user is logged in
*/
if (!!!isAuth || userId !== id)
return { __typename: "Error", error: err, message: mesg };
// if a user is logged in then it works well
}
and my query:
query {
getReports(id: "5f449b73e2ccbc43aa5204d88", patient_id: 0) {
__typename
... on getReportResult {
patient_id
date
}
... on Error {
error
message
}
}
}
The problem is when I tried to pass the wrong id argument or jwt token, it shows the error. if every id and jwt token as header are right then it works like charm. so question is when id or jwt token is wrong, I want to show the Error type to inform user something isn't alright!
I already tried but not working:
type Query {
getReports(id: ID!, patient_id: Int): getReportUnion!
}
union getReportUnion = Error | [getReportResult]
it shows another error, is there any workaround to get rid of this error and show the Error. your answer is valuable to us!
If your field's type is a List, then your resolver must return either an iterable (i.e. an array) or a Promise that resolves to one.
The type for your field is a List ([getReportUnion]). However, inside your resolver, you are returning an object literal:
return { __typename: "Error", error: err, message: mesg }
You should return an array instead:
return [{ __typename: "Error", error: err, message: mesg }]
There is no way for you to return either a List of getReportResult objects or a single Error object. The only way to do that would be to wrap getReportResult with another type and use that type inside your union instead.
type Query {
getReports(id: ID!, patient_id: Int): GetReportPayload!
}
union GetReportPayload = Error | GetReportResults
type GetReportResults {
results: [Report!]!
}
type Report {
id: ID!
patientId: Int!
}
type Error {
error: Boolean!
message: String!
}

How can I use rust Try trait with Option NoneError?

I've written a custom protocol where I've defined my own struct for a frame and it parses from bytes. My function accepts a Vec and parses the elements accordingly. To account for invalid frames, I am returning a Result<Frame> and calling .get() on the byte array. Here's my code:
fn main(){
let emptyvec = Vec::new();
match Frame::from_bytes(emptyvec) {
Err(e) => {
println!("Received invalid frame");
},
Ok(frame) => {
println!("Received valid frame");
}
}
}
struct Frame {
txflag: u8, // indicates if chunked
msgtype: u8, // a flag for message type
sender: u8, // which node ID sent this frame?
routeoffset: u8, // size of array of route for frame
route: Vec<u8>, // a list of node IDs that frame should pass
payload: Vec<u8>, // payload data
}
impl Frame {
/// parse from raw bytes
pub fn from_bytes(bytes: &Vec<u8>) -> std::io::Result<Self> {
let txflag = bytes.get(0)?.clone();
let msgtype = bytes.get(1)?.clone();
let sender = bytes.get(2)?.clone();
let routesoffset = bytes.get(3)?.clone();
let routes = &bytes.get(4..(4+routesoffset as usize))?;
let (left, right) = bytes.split_at(2);
let data = Vec::from(right);
Ok(Frame {
txflag,
msgtype,
sender,
routeoffset: routesoffset,
route: Vec::from(routes),
payload: data
})
}
}
However when I try to use this pattern I get the following compilation error, and when attempting to implement the trait I get an error that the Try trait is unstable.
error[E0277]: `?` couldn't convert the error to `std::io::Error`
--> src/stack/frame.rs:121:34
|
121 | let txflag = bytes.get(0)?.clone();
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `std::io::Error`
Not quite sure how to proceed but I'd like to use stable features to solve this. The goal here is to be able to parse bytes and handle an invalid frame as necessary.
This is probably what you want
use std::io::{Error, ErrorKind};
fn main() {
let emptyvec = Vec::new();
match Frame::from_bytes(&emptyvec) {
Err(e) => {
println!("Received invalid frame");
}
Ok(frame) => {
println!("Received valid frame");
}
}
}
struct Frame {
txflag: u8,
// indicates if chunked
msgtype: u8,
// a flag for message type
sender: u8,
// which node ID sent this frame?
routeoffset: u8,
// size of array of route for frame
route: Vec<u8>,
// a list of node IDs that frame should pass
payload: Vec<u8>, // payload data
}
impl Frame {
/// parse from raw bytes
pub fn from_bytes(bytes: &Vec<u8>) -> std::io::Result<Self> {
let txflag = bytes.get(0).ok_or(Error::from(ErrorKind::InvalidData))?.clone();
let msgtype = bytes.get(1).ok_or(Error::from(ErrorKind::InvalidData))?.clone();
let sender = bytes.get(2).ok_or(Error::from(ErrorKind::InvalidData))?.clone();
let routesoffset = bytes.get(3).ok_or(Error::from(ErrorKind::InvalidData))?.clone();
let routes = bytes
.get(4..(4 + routesoffset as usize))
.ok_or(Error::from(ErrorKind::InvalidData))?
.clone();
let (_, right) = bytes.split_at(2);
let data = Vec::from(right);
Ok(Frame {
txflag,
msgtype,
sender,
routeoffset: routesoffset,
route: Vec::from(routes),
payload: data,
})
}
}
Here is Rust Playground
You are trying to call ? on Option. You have to convert Option to Result (If you still want to use ?).
I want to add to what Đorðe Zeljić said:
As he already pointed out the result of bytes.get(0) is a std::option::Option. When you use the ? operator on that you already left the grounds of stable Rust. This application is only supported in unstable Rust at the moment.
If you want to stay in stable Rust, it's probably best to do what Đorðe wrote. If you want to keep using the ? operator because it produces nicer looking code, here is what's going on:
Rust has a lot of error types, each being only able to represent what they are made for. If you are using a std::io::Result this implicitly uses the error type std::io::Error which is only able to represent typical I/O errors. This type is not able to represent “there was no value when I expected one”. That's why from applying ? to a Option with the None value, you don't get a std::io::Error but a different kind of error: std::option::NoneError.
When your Rust application grows it will happen often, that you have to return a Result that can contain different types of errors. In that case you normally define your own error type (enum), that can represent different kinds of errors. Then for each error, that can be contained, you have to define the From trait on your own enum. This can be a lot of repeated work, so there is a macro in the quick-error crate, that helps with that and implements the From trait automatically for each error that can be contained.
To get your code compiling, you could define the following error enum, that can represent std::io::Error as well as std::option::NoneError:
quick_error! {
#[derive(Debug)]
pub enum FrameError {
IoError(err: std::io::Error) {from() cause(err)}
MissingValue(err: std::option::NoneError) {from()}
}
}
Instead of std::io::Result<Self> your from_bytes function then has to return a std::result::Result that uses your new error type: Result<Self, FrameError>.
Completely assembled that looks like this:
#![feature(try_trait)]
use quick_error::*;
quick_error! {
#[derive(Debug)]
pub enum FrameError {
IoError(err: std::io::Error) {from() cause(err)}
MissingValue(err: std::option::NoneError) {from()}
}
}
fn main() {
let emptyvec = Vec::new();
match Frame::from_bytes(&emptyvec) {
Err(_e) => {
println!("Received invalid frame");
}
Ok(_frame) => {
println!("Received valid frame");
}
}
}
struct Frame {
txflag: u8, // indicates if chunked
msgtype: u8, // a flag for message type
sender: u8, // which node ID sent this frame?
routeoffset: u8, // size of array of route for frame
route: Vec<u8>, // a list of node IDs that frame should pass
payload: Vec<u8>, // payload data
}
impl Frame {
/// parse from raw bytes
pub fn from_bytes(bytes: &Vec<u8>) -> Result<Self, FrameError> {
let txflag = bytes.get(0)?.clone();
let msgtype = bytes.get(1)?.clone();
let sender = bytes.get(2)?.clone();
let routesoffset = bytes.get(3)?.clone();
let routes = bytes.get(4..(4 + routesoffset as usize))?;
let (left, right) = bytes.split_at(2);
let data = Vec::from(right);
Ok(Frame {
txflag,
msgtype,
sender,
routeoffset: routesoffset,
route: Vec::from(routes),
payload: data,
})
}
}
To use the quick-error crate, you have to add the following to your Cargo.toml:
[dependencies]
quick-error = "1.2.3"

Solidity - Solidity code to Input JSON Description

I want to compile my ethereum HelloWorld.sol smart contract. In all the tutorials is that you do it like this:
var solc = require('solc');
var compiledContract = solc.compile(fs.readFileSync('HelloWorld.sol').toString();
where HelloWorld.sol is:
pragma solidity ^0.5.1;
contract HelloWorld {
bytes32 message;
constructor(bytes32 myMessage) public {
message = myMessage;
}
function getMessage() public view returns(bytes32){
return message;
}
}
In other words, I put my raw Solidity contract code into the solc.compile() method. But this process gives me this error in compiledContract:
'{"errors":[{"component":"general","formattedMessage":"* Line 1, Column 1\\n Syntax error: value, object or array expected.\\n* Line 1, Column 2\\n Extra non-whitespace after JSON value.\\n","message":"* Line 1, Column 1\\n Syntax error: value, object or array expected.\\n* Line 1, Column 2\\n Extra non-whitespace after JSON value.\\n","severity":"error","type":"JSONError"}]}'
I was looking for a solution for quite a long time, but the only thing I found is that
"The high-level API consists of a single method, compile, which
expects the Compiler Standard Input and Output JSON."
(link). The standard input JSON looks like some combination of JSON and this solidity code. So my question is -
How to transfer the solidity contract code into a compiler standard input JSON?
Am I correct that this is the only way how to compile the contract?
This code works for me, index.js
const solc = require('solc')
const fs = require('fs')
const CONTRACT_FILE = 'HelloWorld.sol'
const content = fs.readFileSync(CONTRACT_FILE).toString()
const input = {
language: 'Solidity',
sources: {
[CONTRACT_FILE]: {
content: content
}
},
settings: {
outputSelection: {
'*': {
'*': ['*']
}
}
}
}
const output = JSON.parse(solc.compile(JSON.stringify(input)))
for (const contractName in output.contracts[CONTRACT_FILE]) {
console.log(output.contracts[CONTRACT_FILE][contractName].evm.bytecode.object)
}
HelloWorld.sol
contract HelloWorld {
bytes32 message;
constructor(bytes32 myMessage) public {
message = myMessage;
}
function getMessage() public view returns(bytes32){
return message;
}
}
Alternatively, you can run the solc (command line tool) with the below command and with input data
solc --standard-json -o outputDirectory --bin --ast --asm HelloWorld.sol
Where in the above command when --standard-json expects a input json file that you can give.
You can find an example of how an input file should be in the below link.
Source: https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html
const solc = require("solc");
// file system - read and write files to your computer
const fs = require("fs");
// reading the file contents of the smart contract
const fileContent = fs.readFileSync("HelloWorld.sol").toString();
// create an input structure for my solidity compiler
var input = {
language: "Solidity",
sources: {
"HelloWorld.sol": {
content: fileContent,
},
},
settings: {
outputSelection: {
"*": {
"*": ["*"],
},
},
},
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
// console.log("Output: ", output);
const ABI = output.contracts["HelloWorld.sol"]["Demo"].abi;
const byteCode = output.contracts["HelloWorld.sol"]["Demo"].evm.bytecode.object;
// console.log("abi: ",ABI)
// console.log("byte code: ",byteCode)
npm run yorfilename.js

Array of structs init and getter

I'm quite new to Solidity development and I'm struggling with structs for now.
I followed several examples but can't get a way to add a struct to my array of structs. My last try is:
pragma solidity ^0.4.18;
contract Iceicebaby {
struct Parcel {
string state;
string flavour;
uint256 weight;
address holder;
}
Parcel[] public parcels;
function newParcel(string _flavour, uint256 _weight) public {
parcels.length++;
parcels[parcels.length-1].state="ORDERED";
parcels[parcels.length-1].flavour=_flavour;
parcels[parcels.length-1].weight=_weight;
parcels[parcels.length-1].holder=msg.sender;
}
function getParcelsCount () view public returns (uint){
return parcels.length;
}
function getParcel(uint256 index) view public returns (string, string, uint256, address) {
return (parcels[index].state, parcels[index].flavour, parcels[index].weight ,parcels[index].holder);
}}
For now I get :
myInstance.order("Flavour",1) :
{ tx: '0xfad42f92c158557c46496df3fd104d7a09899e641e66748e57b03262f4f5fc62',
receipt:
{ transactionHash: '0xfad42f92c158557c46496df3fd104d7a09899e641e66748e57b03262f4f5fc62',
transactionIndex: 0,
blockHash: '0xc39e94e8e9e9a26fd372ad12d2eba4a72f06251d2f29c4a344cd9e58849d9e49',
blockNumber: 17,
gasUsed: 22168,
cumulativeGasUsed: 22168,
contractAddress: null,
logs: [],
status: 1 },
logs: [] }
myInstance.getParcelsCount()
BigNumber { s: 1, e: 0, c: [ 0 ] }
myInstance.getParcel(0) or myInstance.getParcel(1)
[ '', '', BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x' ]
I tried several other solutions, mapping the structure and stuff like this but can't deal with this thing which should be easy, no?
Also, I can't find how to properly debbug and display logs, is there any standards for this ? I'm using truffle and a local ganache network.
Thanks !
It seems the transaction is not having enough gas to executing the code to store the data.
By default web3 sends 90000 gas (needs confirmation), which is not enough for the transaction you are trying to execute.
Change the following line of code with an extra optional parameter. Here I am providing 150000 gas to the transaction. You can have an easy estimation how much gas is required for a transaction by looking at transaction logs of remix.
myInstance.order("Flavour",1)
myInstance.order("Flavour",1, {from: web3.eth.accounts[0], gas: 150000})

KeystoneJS show error for unqiue index failure

I have a model for tracking redirects like so:
var Redirect = new keystone.List('Redirect', {
});
Redirect.add({
from: { type: String, required: true, initial: true, unique: true },
to: { type: String, required: true, initial: true },
status: { type: Types.Select, options: [{value: 302, label: 'Temporary'},{value: 301, label: 'Permanent'}], default: 302, numeric: true, initial: true }
});
The unique constraint works, I can create new models as long as it doesn't fail to have a unique 'from', but when I do create one with a non-unique 'from' I get an error in the server console but the frontend does nothing.
Error saving changes to Redirect 5664d5860d7c730f09880de1: {
[MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key
error index: keystone.redirects.$from_1 dup key: { : "/herp" }]
name: 'MongoError', code: 11000, err: 'insertDocument :: caused by
:: 11000 E11000 duplicate key error index: keystone.redirects.$from_1
dup key: { : "/herp" }' }
Is there another setting I need to do to get the error to show on the frontend so the user knows what went wrong?
You will have to catch that error in your server logic and present a friendlier flash message to your visitors. At least the database error message is descriptive of the problem duplicate key error ...
exports.flashMessages = function(req, res, next) {
var flashMessages = {
error: req.flash('error')
};
res.locals.messages = _.any(flashMessages,
function(msgs) { return msgs.length }) ? flashMessages
: false;
next();
};
See Common Route Middleware
and to customize the message ensure the passed object contains the appropriate fields for the template
you can provide flash messages in your server logic by adding req.flash
req.flash(
'success',
'Your job has been submitted. Allow 30 days for approval.'
);
See https://github.com/r3dm/shpesfba.org/blob/b83d9e6a3859a83f4b4738e7a13ead08ce611bd3/routes/views/jobForm.js#L44
To display a flash error in the adminUI create an error object and pass that back into the next callback like so
Redirect.schema.pre('save', function(next) {
if (saveFailure) {
var err = new Error('MongoDB is barfing on this');
next(err);
}
}
The difficult part will be to craft your logic with mongoose pre and post lifecycle hooks to catch the mongodb error. Please do some experimenting.
See https://github.com/r3dm/shpesfba.org/blob/b83d9e6a3859a83f4b4738e7a13ead08ce611bd3/models/Event.js#L76