solidity, how to send tuple array data to contract - solidity

my code :
{
"constant": false,
"inputs": [
{
"name": "_id",
"type": "uint256"
},
{
"components": [
{
"name": "trait_type",
"type": "string"
},
{
"name": "display_type",
"type": "string"
},
{
"name": "value",
"type": "uint8"
}
],
"name": "_attr",
"type": "tuple[]"
}
],
"name": "pushAttribute",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
This abi receives a tuple array as input data.
so, I tried encoding according to the data condition.
how can i make send to data tuple array???

If you're sending the value from a JS library, you can just pass an array of JS objects. Example using web3:
const id = 1;
const attr = [
{trait_type: 'foo', display_type: 'bar', value: 1}
];
await contract.methods.pushAttribute(id, attr).send();

Related

Smart contract returns empty

I have a smart contract as you can see below:
pragma solidity ^0.5.2;
contract Coursetro {
string fName="foo";
uint age=123;
function setInstructor(string memory _fName, uint _age) public {
fName = _fName;
age = _age;
}
function getInstructor() public view returns (string memory,uint){
return (fName,age);
}
}
I want to call my function from js with web3. I use testrpc. Here is my js code:
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
var CoursetroContract = new web3.eth.Contract([ { "constant": false, "inputs": [ { "internalType": "string", "name": "_fName", "type": "string" }, { "internalType": "uint256", "name": "_age", "type": "uint256" } ], "name": "setInstructor", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getInstructor", "outputs": [ { "internalType": "string", "name": "", "type": "string" }, { "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ], '0x346dE53Bc9B3a26aeE96f919e471962F5A31d58F');
web3.eth.getAccounts().then(e => web3.eth.defaultAccount = e[0]);
CoursetroContract.methods.getInstructor().call((err, result) => console.log(result))
Everything looks well on remix but when i try to run this js code on my local it writes console empty things like p {0: "", 1: "0"}. But i expect something like p {0: "foo", 1: "123"}. Because i initialized data.

After running my logic app, it shows some error message as" "We couldn't convert to Number.\r\n "

I am collecting data from sensors and upload to AZURE cosmo. My logic app on AZURE keep failing and show the following message
{
"status": 400,
"message": "We couldn't convert to Number.\r\n inner exception: We
couldn't convert to Number.\r\nclientRequestId:xxxxxxx",
"source": "sql-ea.azconn-ea.p.azurewebsites.net"
}
Below are the input data from cosmo. I saw that the input data has shown "ovf" and "inf". I have tried convert the data type of that column to other data type like bigiant and numeric and resubmitted. Still did not fixed that.
{
"Device": "DL084",
"Device_Group": "DLL",
"Time": "2019-09-04T11:45:20.0000000",
"acc_x_avg": "ovf",
"acc_x_stdev": "inf",
"acc_y_avg": "3832.88",
"acc_y_stdev": "2850.45",
"acc_z_avg": "13304.38",
"acc_z_stdev": "2289.86",
"cc_volt": "3.900293",
"cp_volt": "1.940371",
"fp_volt": "0.718475",
"id": "xxxxxxxxxxxxxxxxxxxx",
"ls_volt": "4.882698",
"millis": "1073760.00",
"rs_rpm": "0.00",
"smp_volt": "1.070381"
}
I have also tried to convert the data to string. And it will show
"Failed to execute query. Error: Operand type clash: numeric is
incompatible with ntext"
The question is how can I eliminate this error? How can I know the error is definitely due to the "inf" and "ovf" error?
The logic app code is as below
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"Delete_a_document": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['documentdb']['connectionId']"
}
},
"method": "delete",
"path": "/dbs/#{encodeURIComponent('iot')}/colls/#{encodeURIComponent('messages')}/docs/#{encodeURIComponent(items('For_each')['id'])}"
},
"runAfter": {
"Insert_row": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"Insert_row": {
"inputs": {
"body": {
"Device": "#{item()['device']}",
"Device_Group": "#{items('For_each')['devicegroup']}",
"Time": "#{addHours(addSeconds('1970-01-01 00:00:00', int(items('For_each')['time'])), 8)}",
"acc_x_avg": "#items('For_each')['acc_x_avg']",
"acc_x_stdev": "#items('For_each')['acc_x_stdev']",
"acc_y_avg": "#items('For_each')['acc_y_avg']",
"acc_y_stdev": "#items('For_each')['acc_y_stdev']",
"acc_z_avg": "#items('For_each')['acc_z_avg']",
"acc_z_stdev": "#items('For_each')['acc_z_stdev']",
"cc_volt": "#items('For_each')['cc_volt']",
"cp_volt": "#items('For_each')['cp_volt']",
"fp_volt": "#items('For_each')['fp_volt']",
"id": "#{guid()}",
"ls_volt": "#items('For_each')['ls_volt']",
"millis": "#items('For_each')['millis']",
"rs_rpm": "#items('For_each')['rs_rpm']",
"smp_volt": "#items('For_each')['smp_volt']"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/datasets/default/tables/#{encodeURIComponent(encodeURIComponent('[dbo].[RCD]'))}/items"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"foreach": "#body('Query_documents')?['Documents']",
"runAfter": {
"Query_documents": [
"Succeeded"
]
},
"type": "Foreach"
},
"Query_documents": {
"inputs": {
"body": {
"query": "SELECT \t\t * \nFROM \t\t\tc \nWHERE \t\t\tc.devicegroup = 'DLL' ORDER BY c._ts"
},
"headers": {
"x-ms-max-item-count": 1000
},
"host": {
"connection": {
"name": "#parameters('$connections')['documentdb']['connectionId']"
}
},
"method": "post",
"path": "/dbs/#{encodeURIComponent('iot')}/colls/#{encodeURIComponent('messages')}/query"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Minute",
"interval": 30
},
"type": "Recurrence"
}
}
}
}

Angular6 JSON schema form for Array of Items

I am trying out Angular6 JSON form for my application and stuck in the issue of having array schema
The basic layout looks like
{
"schema": {
"type": "array",
"properties": {
"type": { "type": "string" },
"number": { "type": "string" },
}
},
"layout": [
{
"type": "array",
"items": [ {
"type": "div",
"displayFlex": true,
"flex-direction": "row",
"items": [
{ "key": "type", "flex": "1 1 50px",
"notitle": true, "placeholder": "Type"
},
{ "key": "number", "flex": "4 4 200px",
"notitle": true, "placeholder": "Phone Number"
}
]
} ]
}
],
"data": [
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
]
}
But I am not getting the expected outcome, that is Form is prefilled with the data
[
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
]
Refer: https://hamidihamza.com/Angular6-json-schema-form/
Based on your code there are some parts you may need to revisit.
The schema type should be either an object or boolean based on the documentation http://json-schema.org/latest/json-schema-core.html
Within the schema section, it seems that you want the type and number to be your properties of a JSON instance. Having this you can only pass one instance of data to the framework to fill in your properties because the framework cannot decide on which value to use for your property of type string.
In case of looking for having an array of type and number, you can have a property like "phone number" with the type array. below is an example from angular6-json-schema flex layout example which I think you had as your reference.
"schema": {
...
"phone_numbers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": [ "cell", "home", "work" ] },
"number": { "type": "string" }
},
"required": [ "type", "number" ]
}
And pass your data having something as follows:
"data": {
...
"phone_numbers": [
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
],
}

Pass an already existing Model to next in Loopback

There is Project model
{
"name": "Project",
"plural": "Projects",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"code": {
"type": "string"
},
"startDate": {
"type": "date",
"required": true
},
"endDate": {
"type": "date"
},
"value": {
"type": "number"
},
"infoEN": {
"type": "string"
},
"infoRU": {
"type": "string"
},
"infoAM": {
"type": "string"
},
"externalLinks": {
"type": [
"string"
]
}
},
"validations": [],
"relations": {
"industry": {
"type": "belongsTo",
"model": "Industry",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"service": {
"type": "belongsTo",
"model": "Service",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"tags": {
"type": "hasAndBelongsToMany",
"model": "Tag",
"foreignKey": "",
"options": {
"nestRemoting": true
}
}
},
"acls": [],
"methods": {}
}
And it hasAndBelongsToMany tags
here is Tag model
{
"name": "Tag",
"plural": "Tags",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Now when the relation is created loopback api gives this api endpoint.
POST /Projects/{id}/tags
This creates a new tag into the tags collection and adds it to the project.
But what about adding an already existing tag to the project?
So I figured maybe I add before save hook to the Tag
Here I'll check if the tag exists and then pass the existing one for the relation.
Something like this.
tag.js
'use strict';
module.exports = function(Tag) {
Tag.observe('before save', function(ctx, next) {
console.log(ctx.instance);
Tag.find({name: ctx.instance.name})
next();
});
// Tag.validatesUniquenessOf('name', {message: 'name is not unique'});
};
#HaykSafaryan it just demo to show you how to use tag inside project
var app = require('../../server/server');
module.exports = function(project) {
var tag=app.models.tags
//afterremote it just demo. you can use any method
project.afterRemote('create', function(ctx, next) {
tag.find({name: ctx.instance.name},function(err,result)){
if(err) throw err;
next()
}
});
};
this is just example code to show you how to use update,create ,find ,upsertwithwhere etc. tag for validation you have to setup condition over here it will not take validation which you defined in tags models

JSON SCHEMA - How can i check a values exists in an array

I have a simple question. I have a property groupBy which is an array and contain only two possible values "product" and "date". Now i want to make another property required based upon a value exists in the groupBy array. In this case when my groupBy array contains "date" i want to make resolution required! How can i do that ?
Who can i check if an array contains a value ?
var data = {
"pcsStreamId": 123123,
"start": moment().valueOf(),
"end": moment().valueOf(),
"groupBy" : ["product"]
};
var schema = {
"type": "object",
"properties": {
"pcsStreamId": { "type": "number" },
"start": { "type": "integer", "minimum" : 0 },
"end": { "type": "integer", "minimum" : 0 },
"groupBy": {
"type": "array",
"uniqueItems": true,
"items" : {
"type": "string",
"enum": ["product", "date"]
},
"oneOf": [
{
"contains": { "enum": ["date"] },
"required": ["resolution"]
}
]
},
"resolution" : {
"type": "string",
"enum": ["day", "year", "month", "shift"]
},
},
"required": ["pcsStreamId", "start", "end", "groupBy"]
};
To solve the problem we have to use a boolean logic concept called implication. To put the requirement in boolean logic terms, we would say "groupBy" contains "date" implies that "resolution" is required. Implication can be expressed as "(not A) or B". In other words, either "groupBy" does not contain "date", or "resolution" is required. In this form, it should be more clear how to implement the solution.
{
"type": "object",
"properties": {
"pcsStreamId": { "type": "number" },
"start": { "type": "integer", "minimum": 0 },
"end": { "type": "integer", "minimum": 0 },
"groupBy": {
"type": "array",
"uniqueItems": true,
"items": { "enum": ["product", "date"] }
},
"resolution": { "enum": ["day", "year", "month", "shift"] }
},
"required": ["pcsStreamId", "start", "end", "groupBy"],
"anyOf": [
{ "not": { "$ref": "#/definitions/contains-date" } },
{ "required": ["resolution"] }
],
"definitions": {
"contains-date": {
"properties": {
"groupBy": {
"contains": { "enum": ["date"] }
}
}
}
}
}
Edit
This answer uses the new draft-06 contains keyword. I used it because the questioner used it, but if you are on draft-04, you can use this definition of "contains-date" instead. It uses another logic identity (∃x A <=> ¬∀x ¬A) to get the functionality of the contains keyword.
{
"definitions": {
"contains-date": {
"properties": {
"groupBy": {
"not": {
"items": {
"not": { "enum": ["date"] }
}
}
}
}
}
}
}
Your groupby property seems to be an object. May be its the nested enum property that you are talking about ( since that is an array and contains date and product). However, once you parsed this json to an object you can check something like:
groupby.items.enums.indexOf('date') === -1
array.indexOf(anyItem) returns the index of the item, if present in the array else it returns -1.
Hope that helps