Skip to content

enable hooks for fetching code behind solidity import statements #5

@serapath

Description

@serapath

@todo

  • enable hooks for fetching and caching code behind solidity import statements

I think we should make another module which imports/requires solc-js and many resolvers, and exports a compile function, which takes sourcecode and uses the correct resolvers, so users dont have to bother

maybe here is some resolver code

const compile = require('solc-js')

const resolve_http = async x => await fetch(x).then(r => r.text())
const resolve_swarm = require('resolve-swarm')

const output = await compile(sourceode, async (importpath) => await resolve_http (importpath))

async function compile (sourcecode, getContent) {
  const allimports = await getAllImports(sourcecode)
  const localSources = {}
  // e.g. runs 10x when 10 imports in sourcecode
  for (path of allimports) {
    if (isSwarm(path)) localSources[path] = await resolve_swarm (path)
    if (isHttp(path) localSources[path] = await resolve_http (path)
    // ...
  }
  const output = solcjs(sourcecode, localSources)
  // let localSources = [{
    // path: 'lib.sol',
    // content: 'library L { function f() internal returns (uint) { return 7; } }'
  // }];
  return output
}

const myDB = { } // maybe it looks like:

const sourcecode = `
  import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/a.sol';
  import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/b.sol';
  import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/c.sol';
  import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/d.sol';
  import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/e.sol';
  import 'lib1.sol'
  import 'lib2.sol'
  import 'lib3.sol'
  import 'lib4.sol'
  import 'lib5.sol'

  library OldLibrary {
      function someFunction(uint8 a) public returns(bool);
  }

  contract NewContract {
      function f(uint8 a) public returns (bool) {
          return OldLibrary.someFunction(a);
      }
  }`

test('sourcecode with 10 imports calls callback 10 times', function (t) {
  t.plan(10)
  const output = await compile(sourcecode, async (path) => {
    t.assert(true)
    console.log(path)
    var output
    if (myDB.contains(path)) output = await myDB.get(path)
    else output = new Promise(resolve => {
      resolver.import(path, null, ({ content }) => resolve(content)
    })
    return output
  })
})

/*
  'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/a.sol';
  'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/b.sol';
  'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/c.sol';
  'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/d.sol';
  'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/e.sol';
  'lib1.sol'
  'lib2.sol'
  'lib3.sol'
  'lib4.sol'
  'lib5.sol'
*/

const output = await compile(sourcecode, async (path) => 
    myDB.contains(path) ? await myDB.get(path) : await getImportContent(path)
)

// so "getImportContent(...)" is a replacement for
new Promise(resolve => resolver.import(path, null, ({ content }) => resolve(content))

readCallback function can't be a async function, because emscripten doesn't support it very well.

but I think another workaround is provided "getReadCallback" API.

example 1:

let readCallback = await getReadCallback(sourceCode);
let output = await compiler(sourceCode, readCallback);

example 2:

let localSources = [{
       path: 'lib.sol',
       content: 'library L { function f() internal returns (uint) { return 7; } }'
     }];
 
let readCallback = await getReadCallback(sourceCode, localSources);
let output = await compiler(sourceCode, readCallback);

https://github.com/ethereum-play/solc-js/pull/1/commits/1db7eb24755acf1446487e7693073e2ca1be7301#diff-3b8192acb0d491039ab68dea0b430bfcR62

https://github.com/ethereum-play/solc-js/pull/1/commits/1db7eb24755acf1446487e7693073e2ca1be7301#diff-3b8192acb0d491039ab68dea0b430bfcR39

about imports




keywords

  • combineSource
  • resolver
  • import parser

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions