Solidity - Solidity code to Input JSON Description - npm

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

Related

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

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

Set programmatically jsonValidation for dynamic mapping

I am creating a new vscode extension, and I need to extend the standard usage of the jsonValidation system already present in vscode.
Note : I am talking about the system defined in package.json :
"contributes" : {
"languages": [
{
"id" : "yml",
"filenamePatterns": ["module.service"]
},
{
"id" : "json",
"filenamePatterns": ["module.*"]
}
],
"jsonValidation": [
{
"fileMatch": "module.test",
"url": "./resources/test.schema"
}
]
}
Now, I need to create a dynamic mapping, where the json fields filematch/url are defined from some internal rules (like version and other internal stuff). The standard usage is static : one fileMatch -> one schema.
I want for example to read the version from the json file to validate, and set the schema after that :
{
"version" : "1.1"
}
validation schema must be test-schema.1.1 instead of test-schema.1.0
note : The question is only about the modification of the configuration provided by package.json from the extensions.ts
Thanks for the support
** EDIT since the previous solution was not working in all cases
There is one solution to modify the package.json at the activating of the function.
export function activate(context: vscode.ExtensionContext) {
const myPlugin = vscode.extensions.getExtension("your.plugin.id");
if (!myPlugin)
{
throw new Error("Composer plugin is not found...")
}
// Get the current workspace path to found the schema later.
const folderPath = vscode.workspace.workspaceFolders;
if (!folderPath)
{
return;
}
const baseUri : vscode.Uri = folderPath[0].uri;
let packageJSON = myPlugin.packageJSON;
if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation)
{
let jsonValidation = packageJSON.contributes.jsonValidation;
const schemaUri : vscode.Uri = vscode.Uri.joinPath(baseUri, "/schema/value-0.3.0.json-schema");
const schema = new JsonSchemaMatch("value.ospp", schemaUri)
jsonValidation.push(schema);
}
}
And the json schema class
class JsonSchemaMatch
{
fileMatch: string;
url : string;
constructor(fileMatch : string, url: vscode.Uri)
{
this.fileMatch = fileMatch;
this.url = url.path;
}
}
Another important information is the loading of the element of contributes is not reread after modification, for example
class Language
{
id: string;
filenamePatterns : string[];
constructor(id : string, filenamePatterns: string[])
{
this.id = id;
this.filenamePatterns = filenamePatterns;
}
}
if (packageJSON && packageJSON.contributes && packageJSON.contributes.languages)
{
let languages : Language[] = packageJSON.contributes.languages;
for (let language of languages) {
if (language.id == "json") {
language.filenamePatterns.push("test.my-json-type")
}
}
}
This change has no effect, since the loading of file association is already done (I have not dig for the reason, but I think this is the case)
In this case, creating a settings.json in the workspace directory can do the job:
settings.json
{
"files.associations": {
"target.snmp": "json",
"stack.cfg": "json"
}
}
Be aware that the settings.json can be created by the user with legitimate reason, so don't override it, just fill it.

Whatsapp Web - how to access data now?

It used to be possible to access http://web.whatsapp.com/ with the Store object in JavaScript. A few hours ago, this stopped working. How does it update chat data now? It must save the data somewhere.
I'm using this to get the Store again:
setTimeout(function() {
// Returns promise that resolves to all installed modules
function getAllModules() {
return new Promise((resolve) => {
const id = _.uniqueId("fakeModule_");
window["webpackJsonp"](
[],
{
[id]: function(module, exports, __webpack_require__) {
resolve(__webpack_require__.c);
}
},
[id]
);
});
}
var modules = getAllModules()._value;
// Automatically locate modules
for (var key in modules) {
if (modules[key].exports) {
if (modules[key].exports.default) {
if (modules[key].exports.default.Wap) {
store_id = modules[key].id.replace(/"/g, '"');
}
}
}
}
}, 5000);
function _requireById(id) {
return webpackJsonp([], null, [id]);
}
// Module IDs
var store_id = 0;
var Store = {};
function init() {
Store = _requireById(store_id).default;
console.log("Store is ready" + Store);
}
setTimeout(function() {
init();
}, 7000);
Just copy&paste on the console and wait for the message "Store is ready".
Enjoy!
To explain Pablo's answer in detail, initially we load all the Webpack modules using code based on this How do I require() from the console using webpack?.
Essentially, the getAllModules() returns a promise with all the installed modules in Webpack. Each module can be required by ID using the _requireById(id) which uses the webpackJsonp(...) function that is exposed by Webpack.
Once the modules are loaded, we need to identify which id corresponds to the Store. We search for a module containing exports.default.Wap and assign it's id as the Store ID.
You can find more details on my github wiki here
A faster method:
I grab the source of the "app" and find the store object then
I save it in ZStore global variable. :D
!function(){for(var t of document.getElementsByTagName("script"))t.src.indexOf("/app.")>0&&fetch(t.src,{method:"get"}).then(function(t){return t.text().then(function(t){var e=t.indexOf('var a={};t["default"]')-89;window.ZStore=window.webpackJsonp([],null,JSON.stringify(t.substr(e,10))).default})})}();
window.ZStore will contain the object.
Non minified version:
(function() {
function getStore(url) {
fetch(url, {
"method": 'get'
}).then(function(response) {
return response.text().then(function(data) {
var offset = data.indexOf('var a={};t["default"]') - 89;
window.ZStore = window.webpackJsonp([], null, JSON.stringify(data.substr(offset, 10))).default
});
});
}
for (var e of document.getElementsByTagName("script")) {
if (e.src.indexOf("/app.") > 0) getStore(e.src);
}
})();

SWXMLHash: how to build struct for very deep XML?

I am now working on a complex XML parsing.
Here is the link: https://www.reddit.com/hot/.rss
I use Alamofire to fetch data:
protocol APIUsable {
}
struct API: APIUsable {
static func fetchRedditFeedListData() -> Observable<[Entry]>{
let URL = "https://www.reddit.com/hot/.rss"
return Observable.create { observer in
Alamofire.request(URL).response { response in
guard let data = response.data else {
return
}
do {
let xml = SWXMLHash.parse(data)
let entries: [Entry] = try xml["feed"]["entry"].value()
observer.onNext(entries)
} catch let error as NSError {
print(error.localizedDescription)
}
observer.onCompleted()
}
return Disposables.create()
}
}
}
The following is the struct I build for parsing. And It works well.
struct Entry: XMLIndexerDeserializable {
let title: String
let updated: String
let category: String
let content: String
static func deserialize(_ node: XMLIndexer) throws -> Entry {
return try Entry(
title: node["title"].value(),
updated: node["updated"].value(),
category: node["category"].value(ofAttribute: "term"),
content: node["content"].value()
)
}
}
But I also want to get the image string belong to content, img, src
I have found the solution by myself.
As we can see that there is a HTML in a XML.
So, I use SWXMLHash again to parse content
let xml = SWXMLHash.parse(/*put the content String here*/)
let imageString = xml ["table"]["tr"]["td"][0]["a"]["img"].element?.attribute(by: "src")?.text
then we can get the value of src as string for future use

get is not defined when trying to extends JSONSerializer

I try to define my custom serializer by extending DS.JSONSerialzer.
I pick the serialize function without modifications but when i run Ember,i get this error:
ReferenceError: get is not defined
This is my code :
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
serialize: function(record, options) {
var json = {};
if (options && options.includeId) {
var id = get(record, 'id');
if (id) {
json[get(this, 'primaryKey')] = id;
}
}
record.eachAttribute(function(key, attribute) {
this.serializeAttribute(record, json, key, attribute);
}, this);
record.eachRelationship(function(key, relationship) {
if (relationship.kind === 'belongsTo') {
this.serializeBelongsTo(record, json, relationship);
} else if (relationship.kind === 'hasMany') {
this.serializeHasMany(record, json, relationship);
}
}, this);
return json;
},
});
I didn't change any code. This is the original. Why get is suddenly undefined? It's imported in line 1 in the original file JSONSerialiser
Can you help me?
They have get defined in the scope when creating the serializer, but that doesn't extend outside of their scope into your files.
var get = Ember.get;
var isNone = Ember.isNone;
var map = Ember.ArrayPolyfills.map;
var merge = Ember.merge;
Either replace all of the get methods with Ember.get or define get to be Ember.get