Sorry, but the page you were trying to view does not exist.
59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /pkg/transformer/qtum_genericStringArguments.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/qtumproject/janus/pkg/eth" 6 | "github.com/qtumproject/janus/pkg/qtum" 7 | ) 8 | 9 | type ProxyQTUMGenericStringArguments struct { 10 | *qtum.Qtum 11 | prefix string 12 | method string 13 | } 14 | 15 | var _ ETHProxy = (*ProxyQTUMGenericStringArguments)(nil) 16 | 17 | func (p *ProxyQTUMGenericStringArguments) Method() string { 18 | return p.prefix + "_" + p.method 19 | } 20 | 21 | func (p *ProxyQTUMGenericStringArguments) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 22 | var params eth.StringsArguments 23 | if err := unmarshalRequest(req.Params, ¶ms); err != nil { 24 | // TODO: Correct error code? 25 | return nil, eth.NewInvalidParamsError("couldn't unmarshal request parameters") 26 | } 27 | 28 | if len(params) != 1 { 29 | return nil, eth.NewInvalidParamsError("require 1 argument: the base58 Qtum address") 30 | } 31 | 32 | return p.request(params) 33 | } 34 | 35 | func (p *ProxyQTUMGenericStringArguments) request(params eth.StringsArguments) (*string, eth.JSONRPCError) { 36 | var response string 37 | err := p.Client.Request(p.method, params, &response) 38 | if err != nil { 39 | return nil, eth.NewInvalidRequestError(err.Error()) 40 | } 41 | 42 | return &response, nil 43 | } 44 | -------------------------------------------------------------------------------- /testing/openzeppelin/docker-compose-openzeppelin.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | services: 3 | janus: 4 | image: qtum/janus:dev 5 | build: 6 | context: ../../ 7 | dockerfile: ./Dockerfile 8 | cache_from: 9 | - golang:3.16-alpine 10 | - qtum/janus:dev 11 | ports: 12 | - "23889:23889" 13 | environment: 14 | - QTUM_RPC=http://qtum:testpasswd@qtum:3889 15 | volumes: 16 | - ../../:/src:ro 17 | depends_on: 18 | - qtum 19 | command: --bind 0.0.0.0 --accounts /src/myaccounts.txt --dev 20 | qtum: 21 | ports: 22 | - "3889:3889" 23 | image: qtum/qtum-seeded 24 | build: 25 | context: ../../docker 26 | dockerfile: ./qtum-seeded.Dockerfile 27 | cache_from: 28 | - qtum/qtum-seeded 29 | container_name: qtum_seeded_testchain 30 | command: qtumd -regtest -addrindex -txindex -rpcbind=0.0.0.0:3889 -rpcallowip=0.0.0.0/0 -logevents -rpcuser=qtum -rpcpassword=testpasswd -deprecatedrpc=accounts -printtoconsole 31 | openzeppelin: 32 | image: qtum/janus-openzeppelin 33 | build: 34 | context: . 35 | dockerfile: ./openzeppelin.Dockerfile 36 | cache_from: 37 | - qtum/janus-openzeppelin 38 | environment: 39 | - GENERATE_TO_ADDRESS=qW28njWueNpBXYWj2KDmtFG2gbLeALeHfV 40 | depends_on: 41 | - janus 42 | command: truffle test --network docker 43 | -------------------------------------------------------------------------------- /playground/test-SimpleStore.js: -------------------------------------------------------------------------------- 1 | // YOUR_QTUM_ACCOUNT 2 | const url = require('url'); 3 | 4 | const rpcURL= process.env.ETH_RPC; 5 | const qtumAccount = url.parse(rpcURL).auth.split(":")[0] 6 | 7 | const qtum = require("qtumjs") 8 | const rpc = new qtum.EthRPC(rpcURL, qtumAccount) 9 | const repoData = require("./solar.development.json") 10 | const { 11 | sender, 12 | ...info 13 | } = repoData.contracts['./contracts/SimpleStore.sol'] 14 | const simpleStoreContract = new qtum.Contract(rpc, info) 15 | 16 | const opts = {gasPrice: 100} 17 | 18 | 19 | async function test() { 20 | console.log('exec: await simpleStoreContract.call("get", [], {gasPrice: 100})') 21 | console.log("call", await simpleStoreContract.call("get", [], opts)) 22 | console.log() 23 | 24 | const newVal = Math.floor((Math.random() * 100000000) + 1); 25 | console.log(`exec: await simpleStoreContract.send("set", [${newVal}], {gasPrice: 100})`) 26 | const tx = await simpleStoreContract.send("set", [newVal], opts) 27 | console.log("tx", tx) 28 | console.log() 29 | 30 | console.log('exec: await tx.confirm(0)') 31 | const receipt = await tx.confirm(0) 32 | console.log("receipt", receipt) 33 | console.log() 34 | 35 | console.log('exec: await simpleStoreContract.call("get", [], {gasPrice: 100})') 36 | console.log("call", await simpleStoreContract.call("get", [], opts)) 37 | console.log() 38 | } 39 | 40 | test() 41 | -------------------------------------------------------------------------------- /pkg/transformer/eth_net_listening_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/qtumproject/janus/pkg/internal" 8 | "github.com/qtumproject/janus/pkg/qtum" 9 | ) 10 | 11 | func TestNetListeningInactive(t *testing.T) { 12 | testNetListeningRequest(t, false) 13 | } 14 | 15 | func TestNetListeningActive(t *testing.T) { 16 | testNetListeningRequest(t, true) 17 | } 18 | 19 | func testNetListeningRequest(t *testing.T, active bool) { 20 | //preparing the request 21 | requestParams := []json.RawMessage{} //net_listening has no params 22 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | 27 | mockedClientDoer := internal.NewDoerMappedMock() 28 | qtumClient, err := internal.CreateMockedClient(mockedClientDoer) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | 33 | networkInfoResponse := qtum.NetworkInfoResponse{NetworkActive: active} 34 | err = mockedClientDoer.AddResponseWithRequestID(2, qtum.MethodGetNetworkInfo, networkInfoResponse) 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | 39 | proxyEth := ProxyNetListening{qtumClient} 40 | got, jsonErr := proxyEth.Request(request, internal.NewEchoContext()) 41 | if jsonErr != nil { 42 | t.Fatal(jsonErr) 43 | } 44 | 45 | want := active 46 | 47 | internal.CheckTestResultEthRequestRPC(*request, want, got, t, false) 48 | } 49 | -------------------------------------------------------------------------------- /docker/quick_start/docker-compose.testnet.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | networks: 4 | qtumd_testnet_network: 5 | volumes: 6 | qtumd_testnet_volume: 7 | 8 | services: 9 | janus_testnet: 10 | image: qtum/janus:dev 11 | container_name: janus_testchain 12 | build: 13 | context: ../../ 14 | cache_from: 15 | - golang:1.18-alpine 16 | ports: 17 | - "23889:23889" 18 | environment: 19 | - QTUM_RPC=http://qtum:testpasswd@qtum_testnet:3889 20 | - COMPOSE_PROJECT_NAME=testnet 21 | volumes: 22 | - ../standalone/myaccounts.txt:$GOPATH/github.com/qtumproject/janus/myaccounts.txt 23 | - ../../https:/https 24 | - ../../logs:/logs 25 | depends_on: 26 | - qtum_testnet 27 | command: --bind 0.0.0.0 --port 23889 --ignoreTransactions --accounts $GOPATH/github.com/qtumproject/janus/myaccounts.txt --dev --https-key /https/key.pem --https-cert /https/cert.pem 28 | networks: 29 | - qtumd_testnet_network 30 | 31 | qtum_testnet: 32 | ports: 33 | - "3889:3889" 34 | image: qtum/qtum 35 | container_name: qtum_testnet 36 | command: qtumd -testnet -txindex -addrindex=1 -rpcbind=0.0.0.0:3889 -rpcallowip=0.0.0.0/0 -logevents -rpcuser=qtum -rpcpassword=testpasswd -deprecatedrpc=accounts -printtoconsole 37 | volumes: 38 | - qtumd_testnet_volume:/root/.qtum 39 | networks: 40 | - qtumd_testnet_network 41 | -------------------------------------------------------------------------------- /pkg/notifier/subscription_test.go: -------------------------------------------------------------------------------- 1 | package notifier 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestRollingLimit(t *testing.T) { 9 | l := newRollingLimit(4) 10 | if l.oldest() != 1 { 11 | t.Fatalf("Expected oldest slot to be 1, not %d", l.oldest()) 12 | } 13 | if l.newest() != 0 { 14 | t.Fatalf("Expected newest slot to be 0, not %d", l.newest()) 15 | } 16 | now := time.Now() 17 | first := now.Add(-1 * time.Second) 18 | second := now 19 | third := now.Add(1 * time.Second) 20 | fourth := third.Add(1 * time.Second) 21 | 22 | l.Push(first) 23 | if l.oldest() != 2 { 24 | t.Fatalf("Expected oldest slot to be 2, not %d", l.oldest()) 25 | } 26 | if l.newest() != 1 { 27 | t.Fatalf("Expected newest slot to be 1, not %d", l.newest()) 28 | } 29 | 30 | l.Push(second) 31 | if l.oldest() != 3 { 32 | t.Fatalf("Expected oldest slot to be 3, not %d", l.oldest()) 33 | } 34 | if l.newest() != 2 { 35 | t.Fatalf("Expected newest slot to be 2, not %d", l.newest()) 36 | } 37 | 38 | l.Push(third) 39 | if l.oldest() != 0 { 40 | t.Fatalf("Expected oldest slot to be 0, not %d", l.oldest()) 41 | } 42 | if l.newest() != 3 { 43 | t.Fatalf("Expected newest slot to be 3, not %d", l.newest()) 44 | } 45 | 46 | l.Push(fourth) 47 | if l.oldest() != 1 { 48 | t.Fatalf("Expected oldest slot to be 1, not %d", l.oldest()) 49 | } 50 | if l.newest() != 0 { 51 | t.Fatalf("Expected newest slot to be 0, not %d", l.newest()) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /docker/quick_start/docker-compose.mainnet.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | networks: 4 | qtumd_mainnet_network: 5 | volumes: 6 | qtumd_mainnet_volume: 7 | 8 | services: 9 | janus_mainnet: 10 | image: qtum/janus:latest 11 | container_name: janus_mainnet 12 | build: 13 | context: ../../ 14 | cache_from: 15 | - golang:1.18-alpine 16 | ports: 17 | - "23890:23890" 18 | environment: 19 | - QTUM_RPC=http://qtum:testpasswd@qtum_mainnet:3890 20 | - COMPOSE_PROJECT_NAME=mainnet 21 | volumes: 22 | - ../standalone/myaccounts.txt:$GOPATH/github.com/qtumproject/janus/myaccounts.txt 23 | - ../../https:/https 24 | - ../../logs:/logs 25 | depends_on: 26 | - qtum_mainnet 27 | command: --bind 0.0.0.0 --port 23890 --ignoreTransactions --accounts $GOPATH/github.com/qtumproject/janus/myaccounts.txt --dev --https-key /https/key.pem --https-cert /https/cert.pem 28 | networks: 29 | - qtumd_mainnet_network 30 | 31 | qtum_mainnet: 32 | ports: 33 | - "3890:3890" 34 | image: qtum/qtum 35 | container_name: qtum_mainnet 36 | environment: 37 | - COMPOSE_PROJECT_NAME=mainnet 38 | command: qtumd -txindex -addrindex=1 -rpcbind=0.0.0.0:3890 -rpcallowip=0.0.0.0/0 -rpcuser=qtum -rpcpassword=testpasswd -deprecatedrpc=accounts 39 | volumes: 40 | - qtumd_mainnet_volume:/root/.qtum 41 | networks: 42 | - qtumd_mainnet_network 43 | -------------------------------------------------------------------------------- /docker/quick_start/docker-compose.regtest.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | networks: 4 | qtumd_regtest_network: 5 | volumes: 6 | qtumd_regtest_volume: 7 | 8 | services: 9 | janus_regtest: 10 | image: qtum/janus:dev 11 | container_name: janus_regtest 12 | build: 13 | context: ../../ 14 | cache_from: 15 | - golang:1.18-alpine 16 | ports: 17 | - "23889:23889" 18 | environment: 19 | - QTUM_RPC=http://qtum:testpasswd@qtum_regtest:3889 20 | - COMPOSE_PROJECT_NAME=regtest 21 | volumes: 22 | - ../standalone/myaccounts.txt:$GOPATH/github.com/qtumproject/janus/myaccounts.txt 23 | - ../../https:/https 24 | - ../../logs:/logs 25 | depends_on: 26 | - qtum_regtest 27 | command: --bind 0.0.0.0 --accounts $GOPATH/github.com/qtumproject/janus/myaccounts.txt --log-file /logs/janusLogs.txt --dev --https-key /https/key.pem --https-cert /https/cert.pem 28 | networks: 29 | - qtumd_regtest_network 30 | 31 | qtum_regtest: 32 | ports: 33 | - "3889:3889" 34 | image: qtum/qtum 35 | container_name: qtum_regtest 36 | command: qtumd -regtest -txindex -addrindex=1 -rpcbind=0.0.0.0:3889 -rpcallowip=0.0.0.0/0 -logevents -rpcuser=qtum -rpcpassword=testpasswd -deprecatedrpc=accounts -printtoconsole 37 | volumes: 38 | - qtumd_regtest_volume:/root/.qtum 39 | networks: 40 | - qtumd_regtest_network 41 | -------------------------------------------------------------------------------- /playground/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | solar*.json 75 | /yarn.lock 76 | /.boast.json 77 | /build 78 | /package-lock.json -------------------------------------------------------------------------------- /playground/contracts/openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | import "./ERC20Basic.sol"; 5 | import "../../math/SafeMath.sol"; 6 | 7 | 8 | /** 9 | * @title Basic token 10 | * @dev Basic version of StandardToken, with no allowances. 11 | */ 12 | contract BasicToken is ERC20Basic { 13 | using SafeMath for uint256; 14 | 15 | mapping(address => uint256) balances; 16 | 17 | uint256 totalSupply_; 18 | 19 | /** 20 | * @dev Total number of tokens in existence 21 | */ 22 | function totalSupply() public view returns (uint256) { 23 | return totalSupply_; 24 | } 25 | 26 | /** 27 | * @dev Transfer token for a specified address 28 | * @param _to The address to transfer to. 29 | * @param _value The amount to be transferred. 30 | */ 31 | function transfer(address _to, uint256 _value) public returns (bool) { 32 | require(_value <= balances[msg.sender]); 33 | require(_to != address(0)); 34 | 35 | balances[msg.sender] = balances[msg.sender].sub(_value); 36 | balances[_to] = balances[_to].add(_value); 37 | emit Transfer(msg.sender, _to, _value); 38 | return true; 39 | } 40 | 41 | /** 42 | * @dev Gets the balance of the specified address. 43 | * @param _owner The address to query the the balance of. 44 | * @return An uint256 representing the amount owned by the passed address. 45 | */ 46 | function balanceOf(address _owner) public view returns (uint256) { 47 | return balances[_owner]; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /playground/pet-shop-tutorial/doc/js.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) | [Documentation 2 | table of contents](TOC.md) 3 | 4 | # The JavaScript 5 | 6 | Information about the default JavaScript included in the project. 7 | 8 | ## main.js 9 | 10 | This file can be used to contain or reference your site/app JavaScript code. If 11 | you're working on something more advanced you might replace this file entirely. 12 | That's cool. 13 | 14 | ## plugins.js 15 | 16 | This file can be used to contain all your plugins, such as jQuery plugins and 17 | other 3rd party scripts for a simple site. 18 | 19 | One approach is to put jQuery plugins inside of a `(function($){ ...})(jQuery);` 20 | closure to make sure they're in the jQuery namespace safety blanket. Read more 21 | about [jQuery plugin authoring](https://learn.jquery.com/plugins/). 22 | 23 | By default the `plugins.js` file contains a small script to avoid `console` 24 | errors in browsers that lack a `console`. The script will make sure that, if a 25 | console method isn't available, that method will have the value of empty 26 | function, thus, preventing the browser from throwing an error. 27 | 28 | ## vendor 29 | 30 | This directory can be used to contain all 3rd party library code. 31 | 32 | Our custom build of the Modernizr library is included by 33 | default. You may wish to create your own [custom Modernizr build with the online 34 | builder](https://modernizr.com/download/) or [command line 35 | tool](https://modernizr.com/docs#command-line-config). 36 | -------------------------------------------------------------------------------- /pkg/transformer/eth_getCode.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/labstack/echo" 7 | "github.com/qtumproject/janus/pkg/eth" 8 | "github.com/qtumproject/janus/pkg/qtum" 9 | "github.com/qtumproject/janus/pkg/utils" 10 | ) 11 | 12 | // ProxyETHGetCode implements ETHProxy 13 | type ProxyETHGetCode struct { 14 | *qtum.Qtum 15 | } 16 | 17 | func (p *ProxyETHGetCode) Method() string { 18 | return "eth_getCode" 19 | } 20 | 21 | func (p *ProxyETHGetCode) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 22 | var req eth.GetCodeRequest 23 | if err := unmarshalRequest(rawreq.Params, &req); err != nil { 24 | // TODO: Correct error code? 25 | return nil, eth.NewInvalidParamsError(err.Error()) 26 | } 27 | 28 | return p.request(c.Request().Context(), &req) 29 | } 30 | 31 | func (p *ProxyETHGetCode) request(ctx context.Context, ethreq *eth.GetCodeRequest) (eth.GetCodeResponse, eth.JSONRPCError) { 32 | qtumreq := qtum.GetAccountInfoRequest(utils.RemoveHexPrefix(ethreq.Address)) 33 | 34 | qtumresp, err := p.GetAccountInfo(ctx, &qtumreq) 35 | if err != nil { 36 | if err == qtum.ErrInvalidAddress { 37 | /** 38 | // correct response for an invalid address 39 | { 40 | "jsonrpc": "2.0", 41 | "id": 123, 42 | "result": "0x" 43 | } 44 | **/ 45 | return "0x", nil 46 | } else { 47 | return "", eth.NewCallbackError(err.Error()) 48 | } 49 | } 50 | 51 | // qtum res -> eth res 52 | return eth.GetCodeResponse(utils.AddHexPrefix(qtumresp.Code)), nil 53 | } 54 | -------------------------------------------------------------------------------- /pkg/eth/eth_int.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/pkg/errors" 6 | "math/big" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/qtumproject/janus/pkg/utils" 10 | ) 11 | 12 | type ETHInt struct { 13 | *big.Int 14 | } 15 | 16 | func (i *ETHInt) Hex() string { 17 | return hexutil.EncodeBig(i.Int) 18 | } 19 | 20 | func (i *ETHInt) MarshalJSON() ([]byte, error) { 21 | return json.Marshal(i.Int) 22 | } 23 | 24 | // UnmarshalJSON needs to be able to parse ETHInt from both hex string or number 25 | func (i *ETHInt) UnmarshalJSON(data []byte) (err error) { 26 | if len(data) == 0 { 27 | return errors.New("data must not be empty") 28 | } 29 | 30 | isNumber := func(data []byte) bool { 31 | return data[0] != '"' && data[len(data)-1] != '"' 32 | } 33 | 34 | if isNumber(data) { 35 | i.Int, err = bigIntFromNumber(data) 36 | return err 37 | } 38 | 39 | i.Int, err = bigIntFromHex(data) 40 | return err 41 | } 42 | 43 | func bigIntFromNumber(data json.RawMessage) (*big.Int, error) { 44 | var v *big.Int 45 | if err := json.Unmarshal(data, &v); err != nil { 46 | return nil, errors.Wrap(err, "json unmarshal") 47 | } 48 | return v, nil 49 | } 50 | 51 | func bigIntFromHex(data json.RawMessage) (*big.Int, error) { 52 | var val string 53 | 54 | if err := json.Unmarshal(data, &val); err != nil { 55 | return nil, errors.Wrap(err, "json unmarshal") 56 | } 57 | 58 | i, err := utils.DecodeBig(val) 59 | if err != nil { 60 | return nil, errors.Wrap(err, "decoding error") 61 | } 62 | return i, nil 63 | } 64 | -------------------------------------------------------------------------------- /testing/openzeppelin/truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_directory: "./openzeppelin-contracts/test", 3 | migrations: "./openzeppelin-contracts/migrations", 4 | contracts_directory: "./openzeppelin-contracts/contracts", 5 | contracts_build_directory: "./openzeppelin-contracts/build/output", 6 | mocha: { 7 | reporter: "mocha-spec-json-output-reporter", 8 | reporterOptions: { 9 | fileName: "output.json", 10 | }, 11 | }, 12 | networks: { 13 | development: { 14 | host: "127.0.0.1", 15 | port: 23889, //Switch to 23888 for local HTTP Server, look at Makefile run-janus 16 | network_id: "*", 17 | gas: 3000000, 18 | gasPrice: "0x64", 19 | }, 20 | testing: { 21 | host: "127.0.0.1", 22 | port: 23888, 23 | network_id: "*", 24 | gas: 3000000, 25 | gasPrice: "0x64", 26 | }, 27 | docker: { 28 | host: "janus", 29 | port: 23889, 30 | network_id: "*", 31 | gas: 3000000, 32 | gasPrice: "0x64", 33 | }, 34 | ganache: { 35 | host: "127.0.0.1", 36 | port: 8545, 37 | network_id: "*", 38 | }, 39 | testnet: { 40 | host: "hk1.s.qtum.org", 41 | port: 23889, 42 | network_id: "*", 43 | from: "0x7926223070547d2d15b2ef5e7383e541c338ffe9", 44 | gasPrice: "0x64", 45 | }, 46 | }, 47 | compilers: { 48 | solc: { 49 | version: "0.8.3", 50 | settings: { 51 | optimizer: { 52 | enabled: true, 53 | runs: 1, 54 | }, 55 | }, 56 | }, 57 | }, 58 | }; 59 | -------------------------------------------------------------------------------- /pkg/transformer/eth_blockNumber.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "strings" 5 | "time" 6 | 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | "github.com/labstack/echo" 9 | "github.com/qtumproject/janus/pkg/eth" 10 | "github.com/qtumproject/janus/pkg/qtum" 11 | ) 12 | 13 | // ProxyETHBlockNumber implements ETHProxy 14 | type ProxyETHBlockNumber struct { 15 | *qtum.Qtum 16 | } 17 | 18 | func (p *ProxyETHBlockNumber) Method() string { 19 | return "eth_blockNumber" 20 | } 21 | 22 | func (p *ProxyETHBlockNumber) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 23 | return p.request(c, 5) 24 | } 25 | 26 | func (p *ProxyETHBlockNumber) request(c echo.Context, retries int) (*eth.BlockNumberResponse, eth.JSONRPCError) { 27 | qtumresp, err := p.Qtum.GetBlockCount(c.Request().Context()) 28 | if err != nil { 29 | if retries > 0 && strings.Contains(err.Error(), qtum.ErrTryAgain.Error()) { 30 | ctx := c.Request().Context() 31 | t := time.NewTimer(500 * time.Millisecond) 32 | select { 33 | case <-ctx.Done(): 34 | return nil, eth.NewCallbackError(err.Error()) 35 | case <-t.C: 36 | // fallthrough 37 | } 38 | return p.request(c, retries-1) 39 | } 40 | return nil, eth.NewCallbackError(err.Error()) 41 | } 42 | 43 | // qtum res -> eth res 44 | return p.ToResponse(qtumresp), nil 45 | } 46 | 47 | func (p *ProxyETHBlockNumber) ToResponse(qtumresp *qtum.GetBlockCountResponse) *eth.BlockNumberResponse { 48 | hexVal := hexutil.EncodeBig(qtumresp.Int) 49 | ethresp := eth.BlockNumberResponse(hexVal) 50 | return ðresp 51 | } 52 | -------------------------------------------------------------------------------- /playground/contracts/openzeppelin-solidity/contracts/math/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | /** 5 | * @title SafeMath 6 | * @dev Math operations with safety checks that throw on error 7 | */ 8 | library SafeMath { 9 | 10 | /** 11 | * @dev Multiplies two numbers, throws on overflow. 12 | */ 13 | function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { 14 | // Gas optimization: this is cheaper than asserting 'a' not being zero, but the 15 | // benefit is lost if 'b' is also tested. 16 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 17 | if (a == 0) { 18 | return 0; 19 | } 20 | 21 | c = a * b; 22 | assert(c / a == b); 23 | return c; 24 | } 25 | 26 | /** 27 | * @dev Integer division of two numbers, truncating the quotient. 28 | */ 29 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 30 | // assert(b > 0); // Solidity automatically throws when dividing by 0 31 | // uint256 c = a / b; 32 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 33 | return a / b; 34 | } 35 | 36 | /** 37 | * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). 38 | */ 39 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 40 | assert(b <= a); 41 | return a - b; 42 | } 43 | 44 | /** 45 | * @dev Adds two numbers, throws on overflow. 46 | */ 47 | function add(uint256 a, uint256 b) internal pure returns (uint256 c) { 48 | c = a + b; 49 | assert(c >= a); 50 | return c; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pkg/transformer/eth_hashrate_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "math" 6 | "testing" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/qtumproject/janus/pkg/eth" 10 | "github.com/qtumproject/janus/pkg/internal" 11 | "github.com/qtumproject/janus/pkg/qtum" 12 | ) 13 | 14 | func TestHashrateRequest(t *testing.T) { 15 | //preparing the request 16 | requestParams := []json.RawMessage{} //eth_hashrate has no params 17 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | mockedClientDoer := internal.NewDoerMappedMock() 23 | qtumClient, err := internal.CreateMockedClient(mockedClientDoer) 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | exampleResponse := `{"enabled": true, "staking": false, "errors": "", "currentblocktx": 0, "pooledtx": 0, "difficulty": 4.656542373906925e-010, "search-interval": 0, "weight": 0, "netstakeweight": 0, "expectedtime": 0}` 29 | getHashrateResponse := qtum.GetHashrateResponse{} 30 | unmarshalRequest([]byte(exampleResponse), &getHashrateResponse) 31 | 32 | err = mockedClientDoer.AddResponse(qtum.MethodGetStakingInfo, getHashrateResponse) 33 | if err != nil { 34 | t.Fatal(err) 35 | } 36 | 37 | proxyEth := ProxyETHHashrate{qtumClient} 38 | got, jsonErr := proxyEth.Request(request, internal.NewEchoContext()) 39 | if jsonErr != nil { 40 | t.Fatal(jsonErr) 41 | } 42 | 43 | expected := hexutil.EncodeUint64(math.Float64bits(4.656542373906925e-010)) 44 | want := eth.HashrateResponse(expected) 45 | 46 | internal.CheckTestResultEthRequestRPC(*request, &want, got, t, false) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/transformer/eth_subscribe.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/qtumproject/janus/pkg/eth" 6 | "github.com/qtumproject/janus/pkg/notifier" 7 | "github.com/qtumproject/janus/pkg/qtum" 8 | ) 9 | 10 | // ETHSubscribe implements ETHProxy 11 | type ETHSubscribe struct { 12 | *qtum.Qtum 13 | *notifier.Agent 14 | } 15 | 16 | func (p *ETHSubscribe) Method() string { 17 | return "eth_subscribe" 18 | } 19 | 20 | func (p *ETHSubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 21 | notifier := getNotifier(c) 22 | if notifier == nil { 23 | p.GetLogger().Log("msg", "eth_subscribe only supported over websocket") 24 | /* 25 | // TODO 26 | { 27 | "jsonrpc": "2.0", 28 | "id": 580, 29 | "error": { 30 | "code": -32601, 31 | "message": "The method eth_subscribe does not exist/is not available" 32 | } 33 | } 34 | */ 35 | return nil, eth.NewMethodNotFoundError("eth_subscribe") 36 | } 37 | 38 | var req eth.EthSubscriptionRequest 39 | if err := unmarshalRequest(rawreq.Params, &req); err != nil { 40 | // TODO: Correct error code? 41 | return nil, eth.NewInvalidParamsError(err.Error()) 42 | } 43 | 44 | return p.request(&req, notifier) 45 | } 46 | 47 | func (p *ETHSubscribe) request(req *eth.EthSubscriptionRequest, notifier *notifier.Notifier) (*eth.EthSubscriptionResponse, eth.JSONRPCError) { 48 | notifier.ResponseRequired() 49 | id, err := p.NewSubscription(notifier, req) 50 | response := eth.EthSubscriptionResponse(id) 51 | if err == nil { 52 | return &response, nil 53 | } else { 54 | return &response, eth.NewCallbackError(err.Error()) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pkg/transformer/eth_unsubscribe.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/qtumproject/janus/pkg/eth" 6 | "github.com/qtumproject/janus/pkg/notifier" 7 | "github.com/qtumproject/janus/pkg/qtum" 8 | ) 9 | 10 | // ETHUnsubscribe implements ETHProxy 11 | type ETHUnsubscribe struct { 12 | *qtum.Qtum 13 | *notifier.Agent 14 | } 15 | 16 | func (p *ETHUnsubscribe) Method() string { 17 | return "eth_unsubscribe" 18 | } 19 | 20 | func (p *ETHUnsubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 21 | notifier := getNotifier(c) 22 | if notifier == nil { 23 | p.GetLogger().Log("msg", "eth_unsubscribe only supported over websocket") 24 | /* 25 | // TODO 26 | { 27 | "jsonrpc": "2.0", 28 | "id": 580, 29 | "error": { 30 | "code": -32601, 31 | "message": "The method eth_unsubscribe does not exist/is not available" 32 | } 33 | } 34 | */ 35 | return nil, eth.NewMethodNotFoundError("eth_subscribe") 36 | } 37 | 38 | var req eth.EthUnsubscribeRequest 39 | if err := unmarshalRequest(rawreq.Params, &req); err != nil { 40 | // TODO: Correct error code? 41 | return nil, eth.NewInvalidParamsError(err.Error()) 42 | } 43 | 44 | return p.request(&req, notifier) 45 | } 46 | 47 | func (p *ETHUnsubscribe) request(req *eth.EthUnsubscribeRequest, notifier *notifier.Notifier) (eth.EthUnsubscribeResponse, eth.JSONRPCError) { 48 | if len(*req) != 1 { 49 | // TODO: Correct error code? 50 | return false, eth.NewInvalidParamsError("requires one parameter") 51 | } 52 | param := (*req)[0] 53 | success := notifier.Unsubscribe(param) 54 | return eth.EthUnsubscribeResponse(success), nil 55 | } 56 | -------------------------------------------------------------------------------- /pkg/transformer/eth_net_peerCount_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/qtumproject/janus/pkg/eth" 10 | "github.com/qtumproject/janus/pkg/internal" 11 | "github.com/qtumproject/janus/pkg/qtum" 12 | ) 13 | 14 | func TestPeerCountRequest(t *testing.T) { 15 | for i := 0; i < 10; i++ { 16 | testDesc := fmt.Sprintf("#%d", i) 17 | t.Run(testDesc, func(t *testing.T) { 18 | testPeerCountRequest(t, i) 19 | }) 20 | } 21 | } 22 | 23 | func testPeerCountRequest(t *testing.T, clients int) { 24 | //preparing the request 25 | requestParams := []json.RawMessage{} //net_peerCount has no params 26 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 27 | if err != nil { 28 | t.Fatal(err) 29 | } 30 | 31 | mockedClientDoer := internal.NewDoerMappedMock() 32 | qtumClient, err := internal.CreateMockedClient(mockedClientDoer) 33 | if err != nil { 34 | t.Fatal(err) 35 | } 36 | 37 | getPeerInfoResponse := []qtum.GetPeerInfoResponse{} 38 | for i := 0; i < clients; i++ { 39 | getPeerInfoResponse = append(getPeerInfoResponse, qtum.GetPeerInfoResponse{}) 40 | } 41 | err = mockedClientDoer.AddResponseWithRequestID(2, qtum.MethodGetPeerInfo, getPeerInfoResponse) 42 | if err != nil { 43 | t.Fatal(err) 44 | } 45 | 46 | proxyEth := ProxyNetPeerCount{qtumClient} 47 | got, jsonErr := proxyEth.Request(request, internal.NewEchoContext()) 48 | if jsonErr != nil { 49 | t.Fatal(jsonErr) 50 | } 51 | 52 | want := eth.NetPeerCountResponse(hexutil.EncodeUint64(uint64(clients))) 53 | 54 | internal.CheckTestResultUnspecifiedInput(fmt.Sprint(clients), &want, got, t, false) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/utils/hex.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/hex" 5 | "math/big" 6 | "strings" 7 | 8 | "github.com/btcsuite/btcutil/base58" 9 | // "github.com/decred/base58" 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/common/hexutil" 12 | "github.com/pkg/errors" 13 | ) 14 | 15 | func RemoveHexPrefix(hex string) string { 16 | if strings.HasPrefix(hex, "0x") { 17 | return hex[2:] 18 | } 19 | return hex 20 | } 21 | 22 | func IsEthHexAddress(str string) bool { 23 | return strings.HasPrefix(str, "0x") || common.IsHexAddress("0x"+str) 24 | } 25 | 26 | func AddHexPrefix(hex string) string { 27 | if strings.HasPrefix(hex, "0x") { 28 | return hex 29 | } 30 | return "0x" + hex 31 | } 32 | 33 | func AddHexPrefixIfNotEmpty(hex string) string { 34 | if hex == "" { 35 | return hex 36 | } 37 | return AddHexPrefix(hex) 38 | } 39 | 40 | // DecodeBig decodes a hex string whether input is with 0x prefix or not. 41 | func DecodeBig(input string) (*big.Int, error) { 42 | input = AddHexPrefix(input) 43 | if input == "0x00" { 44 | return big.NewInt(0), nil 45 | } 46 | return hexutil.DecodeBig(input) 47 | } 48 | 49 | // Converts Qtum address to an Ethereum address 50 | func ConvertQtumAddress(address string) (ethAddress string, _ error) { 51 | if n := len(address); n < 22 { 52 | return "", errors.Errorf("invalid address: length is less than 22 bytes - %d", n) 53 | } 54 | 55 | _, _, err := base58.CheckDecode(address) 56 | if err != nil { 57 | return "", errors.Errorf("invalid address") 58 | } 59 | 60 | // Drop Qtum chain prefix and checksum suffix 61 | ethAddrBytes := base58.Decode(address)[1:21] 62 | 63 | return hex.EncodeToString(ethAddrBytes), nil 64 | } 65 | -------------------------------------------------------------------------------- /pkg/internal/tests_transformer.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/pkg/errors" 6 | "github.com/qtumproject/janus/pkg/eth" 7 | ) 8 | 9 | type ETHProxy interface { 10 | Request(*eth.JSONRPCRequest, echo.Context) (interface{}, eth.JSONRPCError) 11 | Method() string 12 | } 13 | 14 | type mockTransformer struct { 15 | proxies map[string]ETHProxy 16 | } 17 | 18 | func (t *mockTransformer) Transform(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 19 | proxy, ok := t.proxies[req.Method] 20 | if !ok { 21 | return nil, eth.NewCallbackError("couldn't get proxy") 22 | } 23 | resp, err := proxy.Request(req, c) 24 | if err != nil { 25 | return nil, eth.NewCallbackError(errors.WithMessagef(err.Error(), "couldn't proxy %s request", req.Method).Error()) 26 | } 27 | return resp, nil 28 | } 29 | 30 | func newTransformer(proxies []ETHProxy) *mockTransformer { 31 | t := &mockTransformer{ 32 | proxies: make(map[string]ETHProxy), 33 | } 34 | 35 | for _, proxy := range proxies { 36 | t.proxies[proxy.Method()] = proxy 37 | } 38 | 39 | return t 40 | } 41 | 42 | func NewMockTransformer(proxies []ETHProxy) *mockTransformer { 43 | return newTransformer(proxies) 44 | } 45 | 46 | type mockETHProxy struct { 47 | method string 48 | response interface{} 49 | } 50 | 51 | func NewMockETHProxy(method string, response interface{}) ETHProxy { 52 | return &mockETHProxy{ 53 | method: method, 54 | response: response, 55 | } 56 | } 57 | 58 | func (e *mockETHProxy) Request(*eth.JSONRPCRequest, echo.Context) (interface{}, eth.JSONRPCError) { 59 | return e.response, nil 60 | } 61 | 62 | func (e *mockETHProxy) Method() string { 63 | return e.method 64 | } 65 | -------------------------------------------------------------------------------- /metamask/README.md: -------------------------------------------------------------------------------- 1 | # Simple VUE project to switch to QTUM network via Metamask 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Customize configuration 19 | See [Configuration Reference](https://cli.vuejs.org/config/). 20 | 21 | ### wallet_addEthereumChain 22 | ``` 23 | // request account access 24 | window.qtum.request({ method: 'eth_requestAccounts' }) 25 | .then(() => { 26 | // add chain 27 | window.qtum.request({ 28 | method: "wallet_addEthereumChain", 29 | params: [{ 30 | { 31 | chainId: '0x22B9', 32 | chainName: 'Qtum Testnet', 33 | rpcUrls: ['https://localhost:23889'], 34 | blockExplorerUrls: ['https://testnet.qtum.info/'], 35 | iconUrls: [ 36 | 'https://qtum.info/images/metamask_icon.svg', 37 | 'https://qtum.info/images/metamask_icon.png', 38 | ], 39 | nativeCurrency: { 40 | decimals: 18, 41 | symbol: 'QTUM', 42 | }, 43 | } 44 | }], 45 | } 46 | }); 47 | ``` 48 | 49 | # Known issues 50 | - Metamask requires https for `rpcUrls` so that must be enabled 51 | - Either directly through Janus with `--https-key ./path --https-cert ./path2` see [SSL](../README.md#ssl) 52 | - Through the Makefile `make docker-configure-https && make run-janus-https` 53 | - Or do it yourself with a proxy (eg, nginx) 54 | -------------------------------------------------------------------------------- /playground/pet-shop-tutorial/doc/css.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) | [Documentation 2 | table of contents](TOC.md) 3 | 4 | # The CSS 5 | 6 | HTML5 Boilerplate's CSS includes: 7 | 8 | * [Normalize.css](#normalizecss) 9 | * [main.css](#maincss) 10 | 11 | ## Normalize.css 12 | 13 | In order to make browsers render all elements more consistently and in line with 14 | modern standards, we include Normalize.css — a modern, HTML5-ready alternative 15 | to CSS resets. 16 | 17 | As opposed to CSS resets, Normalize.css: 18 | 19 | * targets only the styles that need normalizing 20 | * preserves useful browser defaults rather than erasing them 21 | * corrects bugs and common browser inconsistencies 22 | * improves usability with subtle improvements 23 | * doesn't clutter the debugging tools 24 | * has better documentation 25 | 26 | For more information about Normalize.css, please refer to its [project 27 | page](https://necolas.github.io/normalize.css/). 28 | 29 | ## main.css 30 | 31 | Several base styles are included that build upon `Normalize.css`. These styles: 32 | 33 | * provide basic typography settings that improve text readability 34 | * protect against unwanted `text-shadow` during text highlighting 35 | * tweak the default alignment of some elements (e.g.: `img`, `video`, 36 | `fieldset`, `textarea`) 37 | * style the prompt that is displayed to users using an outdated browser 38 | * and more... 39 | 40 | These styles are included in 41 | [main.css](https://github.com/h5bp/html5-boilerplate/blob/master/dist/css/main.css). 42 | See the [main.css](https://github.com/h5bp/main.css) project 43 | [documentation](https://github.com/h5bp/main.css/blob/master/README.md#features) 44 | for a full discussion of these styles. 45 | -------------------------------------------------------------------------------- /pkg/transformer/eth_chainId_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/qtumproject/janus/pkg/eth" 8 | "github.com/qtumproject/janus/pkg/internal" 9 | "github.com/qtumproject/janus/pkg/qtum" 10 | ) 11 | 12 | func TestChainIdMainnet(t *testing.T) { 13 | testChainIdsImpl(t, "main", "0x51") 14 | } 15 | 16 | func TestChainIdTestnet(t *testing.T) { 17 | testChainIdsImpl(t, "test", "0x22b9") 18 | } 19 | 20 | func TestChainIdRegtest(t *testing.T) { 21 | testChainIdsImpl(t, "regtest", "0x22ba") 22 | } 23 | 24 | func TestChainIdUnknown(t *testing.T) { 25 | testChainIdsImpl(t, "???", "0x22ba") 26 | } 27 | 28 | func testChainIdsImpl(t *testing.T, chain string, expected string) { 29 | //preparing request 30 | requestParams := []json.RawMessage{} 31 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 32 | if err != nil { 33 | t.Fatal(err) 34 | } 35 | 36 | mockedClientDoer := internal.NewDoerMappedMock() 37 | 38 | //preparing client response 39 | getBlockCountResponse := qtum.GetBlockChainInfoResponse{Chain: chain} 40 | err = mockedClientDoer.AddResponseWithRequestID(2, qtum.MethodGetBlockChainInfo, getBlockCountResponse) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | 45 | qtumClient, err := internal.CreateMockedClientForNetwork(mockedClientDoer, qtum.ChainAuto) 46 | if err != nil { 47 | t.Fatal(err) 48 | } 49 | 50 | //preparing proxy & executing request 51 | proxyEth := ProxyETHChainId{qtumClient} 52 | got, jsonErr := proxyEth.Request(request, internal.NewEchoContext()) 53 | if jsonErr != nil { 54 | t.Fatal(jsonErr) 55 | } 56 | 57 | want := eth.ChainIdResponse(expected) 58 | 59 | internal.CheckTestResultEthRequestRPC(*request, want, got, t, false) 60 | } 61 | -------------------------------------------------------------------------------- /playground/contracts/openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "./StandardToken.sol"; 4 | import "../../ownership/Ownable.sol"; 5 | 6 | 7 | /** 8 | * @title Mintable token 9 | * @dev Simple ERC20 Token example, with mintable token creation 10 | * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol 11 | */ 12 | contract MintableToken is StandardToken, Ownable { 13 | event Mint(address indexed to, uint256 amount); 14 | event MintFinished(); 15 | 16 | bool public mintingFinished = false; 17 | 18 | 19 | modifier canMint() { 20 | require(!mintingFinished); 21 | _; 22 | } 23 | 24 | modifier hasMintPermission() { 25 | require(msg.sender == owner); 26 | _; 27 | } 28 | 29 | /** 30 | * @dev Function to mint tokens 31 | * @param _to The address that will receive the minted tokens. 32 | * @param _amount The amount of tokens to mint. 33 | * @return A boolean that indicates if the operation was successful. 34 | */ 35 | function mint( 36 | address _to, 37 | uint256 _amount 38 | ) 39 | hasMintPermission 40 | canMint 41 | public 42 | returns (bool) 43 | { 44 | totalSupply_ = totalSupply_.add(_amount); 45 | balances[_to] = balances[_to].add(_amount); 46 | emit Mint(_to, _amount); 47 | emit Transfer(address(0), _to, _amount); 48 | return true; 49 | } 50 | 51 | /** 52 | * @dev Function to stop minting new tokens. 53 | * @return True if the operation was successful. 54 | */ 55 | function finishMinting() onlyOwner canMint public returns (bool) { 56 | mintingFinished = true; 57 | emit MintFinished(); 58 | return true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pkg/analytics/analytics.go: -------------------------------------------------------------------------------- 1 | package analytics 2 | 3 | import "sync" 4 | 5 | type Analytics struct { 6 | success int 7 | failures int 8 | lastRequest int 9 | lastRequests []bool 10 | totalRequests int 11 | 12 | mutex sync.RWMutex 13 | } 14 | 15 | func NewAnalytics(requests int) *Analytics { 16 | analytics := &Analytics{ 17 | success: 0, 18 | failures: 0, 19 | lastRequest: 0, 20 | lastRequests: make([]bool, requests), 21 | totalRequests: requests, 22 | } 23 | 24 | return analytics 25 | } 26 | 27 | func (a *Analytics) GetSuccessRate() float32 { 28 | a.mutex.RLock() 29 | defer a.mutex.RUnlock() 30 | 31 | total := a.success + a.failures 32 | 33 | if total != a.totalRequests { 34 | // if there are not enough requests, don't let the first request get reported as an alert 35 | return 1 36 | } 37 | 38 | return float32(a.success) / float32(total) 39 | } 40 | 41 | func (a *Analytics) Success() { 42 | a.bump(true) 43 | } 44 | 45 | func (a *Analytics) Failure() { 46 | a.bump(false) 47 | } 48 | 49 | func (a *Analytics) bump(success bool) { 50 | a.mutex.Lock() 51 | defer a.mutex.Unlock() 52 | 53 | total := a.success + a.failures 54 | 55 | if success { 56 | a.success++ 57 | } else { 58 | a.failures++ 59 | } 60 | 61 | if total >= a.totalRequests { 62 | // push the last request off 63 | if a.lastRequests[a.lastRequest] { 64 | a.success-- 65 | } else { 66 | a.failures-- 67 | } 68 | 69 | if a.success < 0 { 70 | panic("internal analytics success count is < 0") 71 | } 72 | 73 | if a.failures < 0 { 74 | panic("internal analytics failure count is < 0") 75 | } 76 | } 77 | 78 | a.lastRequests[a.lastRequest] = success 79 | a.lastRequest = (a.lastRequest + 1) % a.totalRequests 80 | } 81 | -------------------------------------------------------------------------------- /pkg/transformer/eth_getFilterLogs.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/labstack/echo" 8 | "github.com/qtumproject/janus/pkg/eth" 9 | ) 10 | 11 | // ProxyETHGetFilterLogs implements ETHProxy 12 | type ProxyETHGetFilterLogs struct { 13 | *ProxyETHGetFilterChanges 14 | } 15 | 16 | func (p *ProxyETHGetFilterLogs) Method() string { 17 | return "eth_getFilterLogs" 18 | } 19 | 20 | func (p *ProxyETHGetFilterLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 21 | 22 | filter, err := processFilter(p.ProxyETHGetFilterChanges, rawreq) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | switch filter.Type { 28 | case eth.NewFilterTy: 29 | return p.request(c.Request().Context(), filter) 30 | default: 31 | return nil, eth.NewInvalidParamsError("filter not found") 32 | } 33 | } 34 | 35 | func (p *ProxyETHGetFilterLogs) request(ctx context.Context, filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err eth.JSONRPCError) { 36 | qtumresp = make(eth.GetFilterChangesResponse, 0) 37 | 38 | _lastBlockNumber, ok := filter.Data.Load("lastBlockNumber") 39 | if !ok { 40 | return qtumresp, eth.NewCallbackError("Could not get lastBlockNumber") 41 | } 42 | lastBlockNumber := _lastBlockNumber.(uint64) 43 | 44 | _toBlock, ok := filter.Data.Load("toBlock") 45 | if !ok { 46 | return qtumresp, eth.NewCallbackError("Could not get toBlock") 47 | } 48 | toBlock := _toBlock.(uint64) 49 | 50 | searchLogsReq, err := p.ProxyETHGetFilterChanges.toSearchLogsReq(filter, big.NewInt(int64(lastBlockNumber)), big.NewInt(int64(toBlock))) 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | return p.ProxyETHGetFilterChanges.doSearchLogs(ctx, searchLogsReq) 56 | 57 | } 58 | -------------------------------------------------------------------------------- /pkg/transformer/web3_sha3_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/qtumproject/janus/pkg/internal" 8 | ) 9 | 10 | func TestWeb3Sha3Request(t *testing.T) { 11 | values := make(map[string]string) 12 | values[""] = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" 13 | values["0x00"] = "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" 14 | values["0x68656c6c6f20776f726c64"] = "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad" 15 | 16 | for input, want := range values { 17 | requestParams := []json.RawMessage{[]byte(`"` + input + `"`)} 18 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 19 | if err != nil { 20 | t.Fatal(err) 21 | } 22 | 23 | web3Sha3 := Web3Sha3{} 24 | got, jsonErr := web3Sha3.Request(request, nil) 25 | if jsonErr != nil { 26 | t.Fatal(jsonErr) 27 | } 28 | 29 | internal.CheckTestResultUnspecifiedInput(input, want, got, t, false) 30 | } 31 | } 32 | 33 | func TestWeb3Sha3Errors(t *testing.T) { 34 | testWeb3Sha3Errors(t, []json.RawMessage{}, "missing value for required argument 0") 35 | testWeb3Sha3Errors(t, []json.RawMessage{[]byte(`"0x00"`), []byte(`"0x00"`)}, "too many arguments, want at most 1") 36 | } 37 | 38 | func testWeb3Sha3Errors(t *testing.T, input []json.RawMessage, want string) { 39 | requestParams := input 40 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | 45 | web3Sha3 := Web3Sha3{} 46 | _, jsonErr := web3Sha3.Request(request, nil) 47 | got := jsonErr.Message() 48 | 49 | // TODO: Expand to also check for correct error code? 50 | internal.CheckTestResultUnspecifiedInputMarshal(input, want, got, t, false) 51 | } 52 | -------------------------------------------------------------------------------- /playground/test/truffle-test-myToken.js: -------------------------------------------------------------------------------- 1 | const MyToken = artifacts.require("MyToken"); 2 | 3 | contract("MyToken", async accounts => { 4 | 5 | it("Has been deployed", async () => { 6 | const myTokenDeployed = await MyToken.deployed(); 7 | assert(myTokenDeployed, "contract has been deployed"); 8 | console.log("Address is: ", myTokenDeployed.address) 9 | }); 10 | 11 | it("should perform transactions correctly", async () => { 12 | 13 | const acc1 = accounts[0]; 14 | console.log("acc1 address: ", acc1); 15 | const acc2 = accounts[1]; 16 | console.log("acc2 address: ", acc2); 17 | 18 | const amount = 10; 19 | 20 | const myToken = await MyToken.deployed(); 21 | 22 | let balance = await myToken.balanceOf(acc1); 23 | let acc1StartingBalance = balance.toNumber(); 24 | console.log("starting balance of acc1: ", acc1StartingBalance); 25 | 26 | balance = await myToken.balanceOf(acc2); 27 | let acc2StartingBalance = balance.toNumber(); 28 | console.log("starting balance of acc2: ", acc2StartingBalance); 29 | 30 | await myToken.mint(acc1, 100).then((receipt) => { console.log("receipt: ", receipt)}); 31 | balance = await myToken.balanceOf(acc1); 32 | let acc1Balance = balance.toNumber(); 33 | console.log("new balance of acc1: ", acc1Balance); 34 | 35 | await myToken.transfer(acc2, amount, {from: acc1}).then((receipt) => { console.log("receipt: ", receipt)}); 36 | balance = await myToken.balanceOf(acc2); 37 | let acc2Balance = balance.toNumber(); 38 | balance = await myToken.balanceOf(acc1); 39 | acc1Balance = balance.toNumber(); 40 | console.log("new balance of acc1 after transfer to acc2: ", acc1Balance); 41 | console.log("new balance of acc2 after transfer to acc1: ", acc2Balance); 42 | 43 | }); 44 | 45 | }); -------------------------------------------------------------------------------- /playground/pet-shop-tutorial/doc/TOC.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) 2 | 3 | ## Getting started 4 | 5 | * [Usage](usage.md) — Overview of the project contents. 6 | * [FAQ](faq.md) — Frequently asked questions along with their answers. 7 | 8 | ## HTML5 Boilerplate core 9 | 10 | * [HTML](html.md) — Guide to the default HTML. 11 | * [CSS](css.md) — Guide to the default CSS. 12 | * [JavaScript](js.md) — Guide to the default JavaScript. 13 | * [Everything else](misc.md). 14 | 15 | ## Development 16 | 17 | * [Extending and customizing HTML5 Boilerplate](extend.md) — Going further with 18 | the boilerplate. 19 | 20 | ## Related projects 21 | 22 | The [H5BP organization](https://github.com/h5bp) maintains several projects that 23 | complement HTML5 Boilerplate, projects that can help you improve different 24 | aspects of your website/web app (e.g.: the performance, security, etc.). 25 | 26 | * [Server Configs](https://github.com/h5bp/server-configs) — Fast and smart 27 | configurations for web servers such as Apache and Nginx. 28 | * [Apache](https://github.com/h5bp/server-configs-apache) 29 | * [Google App Engine (GAE)](https://github.com/h5bp/server-configs-gae) 30 | * [Internet Information Services 31 | (IIS)](https://github.com/h5bp/server-configs-iis) 32 | * [lighttpd](https://github.com/h5bp/server-configs-lighttpd) 33 | * [Nginx](https://github.com/h5bp/server-configs-nginx) 34 | * [Node.js](https://github.com/h5bp/server-configs-node) 35 | * [Front-end Developer Interview Questions](https://github.com/h5bp/Front-end-Developer-Interview-Questions) 36 | * [create-html5-boilerplate](https://github.com/h5bp/create-html5-boilerplate) — Quick start HTML5 Boilerplate development 37 | * [main.css](https://github.com/h5bp/main.css) — the main.css file included with HTML5 Boilerplate 38 | -------------------------------------------------------------------------------- /pkg/transformer/eth_newFilter.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | 7 | "github.com/dcb9/go-ethereum/common/hexutil" 8 | "github.com/labstack/echo" 9 | "github.com/qtumproject/janus/pkg/eth" 10 | "github.com/qtumproject/janus/pkg/qtum" 11 | ) 12 | 13 | // ProxyETHNewFilter implements ETHProxy 14 | type ProxyETHNewFilter struct { 15 | *qtum.Qtum 16 | filter *eth.FilterSimulator 17 | } 18 | 19 | func (p *ProxyETHNewFilter) Method() string { 20 | return "eth_newFilter" 21 | } 22 | 23 | func (p *ProxyETHNewFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { 24 | var req eth.NewFilterRequest 25 | if err := json.Unmarshal(rawreq.Params, &req); err != nil { 26 | // TODO: Correct error code? 27 | return nil, eth.NewInvalidParamsError(err.Error()) 28 | } 29 | 30 | return p.request(c.Request().Context(), &req) 31 | } 32 | 33 | func (p *ProxyETHNewFilter) request(ctx context.Context, ethreq *eth.NewFilterRequest) (*eth.NewFilterResponse, eth.JSONRPCError) { 34 | 35 | from, err := getBlockNumberByRawParam(ctx, p.Qtum, ethreq.FromBlock, true) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | to, err := getBlockNumberByRawParam(ctx, p.Qtum, ethreq.ToBlock, true) 41 | if err != nil { 42 | return nil, err 43 | } 44 | 45 | filter := p.filter.New(eth.NewFilterTy, ethreq) 46 | filter.Data.Store("lastBlockNumber", from.Uint64()) 47 | 48 | filter.Data.Store("toBlock", to.Uint64()) 49 | 50 | if len(ethreq.Topics) > 0 { 51 | topics, err := eth.TranslateTopics(ethreq.Topics) 52 | if err != nil { 53 | return nil, eth.NewCallbackError(err.Error()) 54 | } 55 | filter.Data.Store("topics", qtum.NewSearchLogsTopics(topics)) 56 | } 57 | resp := eth.NewFilterResponse(hexutil.EncodeUint64(filter.ID)) 58 | return &resp, nil 59 | } 60 | -------------------------------------------------------------------------------- /testing/revert-reasons/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | .idea 14 | 15 | .DS_Store 16 | build 17 | 18 | # Logs 19 | logs 20 | *.log 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | .txt 25 | 26 | # Runtime data 27 | pids 28 | *.pid 29 | *.seed 30 | *.pid.lock 31 | 32 | # Directory for instrumented libs generated by jscoverage/JSCover 33 | lib-cov 34 | 35 | # Coverage directory used by tools like istanbul 36 | coverage 37 | 38 | # nyc test coverage 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 42 | .grunt 43 | 44 | # Bower dependency directory (https://bower.io/) 45 | bower_components 46 | 47 | # node-waf configuration 48 | .lock-wscript 49 | 50 | # Compiled binary addons (https://nodejs.org/api/addons.html) 51 | build/Release 52 | 53 | # Dependency directories 54 | node_modules/ 55 | jspm_packages/ 56 | 57 | # TypeScript v1 declaration files 58 | typings/ 59 | 60 | # Optional npm cache directory 61 | .npm 62 | 63 | # Optional eslint cache 64 | .eslintcache 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variables file 76 | .env 77 | 78 | # parcel-bundler cache (https://parceljs.org/) 79 | .cache 80 | 81 | # next.js build output 82 | .next 83 | 84 | # nuxt.js build output 85 | .nuxt 86 | 87 | # vuepress build output 88 | .vuepress/dist 89 | 90 | # Serverless directories 91 | .serverless 92 | solar*.json 93 | /yarn.lock 94 | /.boast.json 95 | /build 96 | /package-lock.json 97 | /package.json 98 | *.txt -------------------------------------------------------------------------------- /testing/aave/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import { HardhatUserConfig } from 'hardhat/types'; 4 | // @ts-ignore 5 | 6 | require('dotenv').config(); 7 | 8 | import '@nomiclabs/hardhat-ethers'; 9 | import '@nomiclabs/hardhat-waffle'; 10 | import 'hardhat-gas-reporter'; 11 | import 'hardhat-typechain'; 12 | import '@tenderly/hardhat-tenderly'; 13 | 14 | const SKIP_LOAD = true; 15 | 16 | // Prevent to load scripts before compilation and typechain 17 | if (!SKIP_LOAD) { 18 | ['misc', 'migrations', 'dev', 'full', 'verifications', 'deployments', 'helpers'].forEach( 19 | (folder) => { 20 | const tasksPath = path.join(__dirname, 'tasks', folder); 21 | fs.readdirSync(tasksPath) 22 | .filter((pth) => pth.includes('.ts')) 23 | .forEach((task) => { 24 | require(`${tasksPath}/${task}`); 25 | }); 26 | } 27 | ); 28 | } 29 | 30 | require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`); 31 | 32 | 33 | const buidlerConfig: HardhatUserConfig = { 34 | solidity: { 35 | version: '0.6.12', 36 | settings: { 37 | optimizer: {enabled: true, runs: 1}, 38 | }, 39 | }, 40 | typechain: { 41 | outDir: 'types', 42 | target: 'ethers-v5', 43 | }, 44 | mocha: { 45 | timeout: 0, 46 | }, 47 | defaultNetwork: "development", 48 | networks: { 49 | development: { 50 | url: "http://127.0.0.1:23889", 51 | gas: "auto", 52 | gasPrice: "auto", 53 | timeout: 600000 54 | }, 55 | ganache: { 56 | url: "http://127.0.0.1:8545", 57 | gas: "auto", 58 | }, 59 | testnet: { 60 | url: "http://hk1.s.qtum.org:23889", 61 | from: "0x7926223070547d2d15b2ef5e7383e541c338ffe9", 62 | gas: "auto", 63 | gasPrice: "auto" 64 | }, 65 | }, 66 | }; 67 | 68 | export default buidlerConfig; 69 | -------------------------------------------------------------------------------- /pkg/eth/util.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | "github.com/qtumproject/janus/pkg/utils" 6 | ) 7 | 8 | var ErrInvalidTopics = errors.New("Invalid topics") 9 | 10 | /** 11 | translateTopics takes in an ethReq's topics field and translates it to a it's equivalent QtumReq 12 | topics (optional) has a max lenght of 4 13 | 14 | Topics are order-dependent. A transaction with a log with topics [A, B] will be matched by the following topic filters: 15 | 16 | [] “anything” 17 | [A] “A in first position (and anything after)” 18 | [null, B] “anything in first position AND B in second position (and anything after)” 19 | [A, B] “A in first position AND B in second position (and anything after)” 20 | [[A, B], [A, B]] “(A OR B) in first position AND (A OR B) in second position (and anything after)” 21 | */ 22 | func TranslateTopics(ethTopics []interface{}) ([][]string, error) { 23 | 24 | var topics [][]string 25 | nilCount := 0 26 | 27 | for _, topic := range ethTopics { 28 | switch topic.(type) { 29 | case []string: 30 | stringTopics := []string{} 31 | for _, t := range topic.([]string) { 32 | stringTopics = append(stringTopics, utils.RemoveHexPrefix(t)) 33 | } 34 | topics = append(topics, stringTopics) 35 | case string: 36 | topics = append(topics, []string{utils.RemoveHexPrefix(topic.(string))}) 37 | case nil: 38 | nilCount++ 39 | topics = append(topics, nil) 40 | case []interface{}: 41 | stringTopics := []string{} 42 | for _, t := range topic.([]interface{}) { 43 | if stringTopic, ok := t.(string); ok { 44 | stringTopics = append(stringTopics, utils.RemoveHexPrefix(stringTopic)) 45 | } else { 46 | return nil, ErrInvalidTopics 47 | } 48 | } 49 | topics = append(topics, stringTopics) 50 | } 51 | } 52 | 53 | return topics, nil 54 | 55 | } 56 | -------------------------------------------------------------------------------- /pkg/qtum/client_test.go: -------------------------------------------------------------------------------- 1 | package qtum 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestComputeBackoff(t *testing.T) { 9 | backoffOne := computeBackoff(0, false) 10 | if backoffOne != 250*time.Millisecond { 11 | t.Errorf("Unexpected backoff time %d != %d", backoffOne.Milliseconds(), (250 * time.Millisecond).Milliseconds()) 12 | } 13 | backoffTwo := computeBackoff(1, false) 14 | if backoffTwo != 500*time.Millisecond { 15 | t.Errorf("Unexpected backoff time %d != %d", backoffTwo.Milliseconds(), (500 * time.Millisecond).Milliseconds()) 16 | } 17 | backoffThree := computeBackoff(2, false) 18 | if backoffThree != 1000*time.Millisecond { 19 | t.Errorf("Unexpected backoff time %d != %d", backoffThree.Milliseconds(), (1000 * time.Millisecond).Milliseconds()) 20 | } 21 | maxBackoff := computeBackoff(10, false) 22 | if maxBackoff != 2000*time.Millisecond { 23 | t.Errorf("Unexpected backoff time %d != %d", maxBackoff.Milliseconds(), (2000 * time.Millisecond).Milliseconds()) 24 | } 25 | overflow := computeBackoff(1000000, false) 26 | if overflow != 2000*time.Millisecond { 27 | t.Errorf("Unexpected backoff time %d != %d", overflow.Milliseconds(), (2000 * time.Millisecond).Milliseconds()) 28 | } 29 | } 30 | 31 | func TestComputeBackoffWithRandom(t *testing.T) { 32 | randomRange := time.Duration(250) 33 | for i := 0; i < 10000; i++ { 34 | backoff := computeBackoff(0, true) 35 | min := (250 - randomRange) * time.Millisecond 36 | max := (250 + randomRange) * time.Millisecond 37 | if backoff < min || backoff > max { 38 | t.Fatalf("Unexpected backoff time %d <= (%d) <= %d", min, backoff.Milliseconds(), max) 39 | } 40 | } 41 | 42 | overflow := computeBackoff(1000000, true) 43 | if overflow != 2000*time.Millisecond { 44 | t.Fatalf("Unexpected backoff time %d != %d", overflow.Milliseconds(), (2000 * time.Millisecond).Milliseconds()) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pkg/eth/eth_address.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | 7 | "github.com/pkg/errors" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var ErrNoHexPrefix = errors.New("Missing 0x prefix") 13 | var ErrInvalidLength = errors.New("Invalid length") 14 | 15 | type ETHAddress struct { 16 | address string 17 | } 18 | 19 | func NewETHAddress(address string) (ETHAddress, error) { 20 | var ethAddress ETHAddress 21 | if !strings.HasPrefix(address, `"`) { 22 | address = `"` + address 23 | } 24 | 25 | if !strings.HasSuffix(address, `"`) { 26 | address = address + `"` 27 | } 28 | 29 | err := json.Unmarshal([]byte(address), ðAddress) 30 | if err != nil { 31 | return ethAddress, err 32 | } 33 | return ethAddress, nil 34 | } 35 | 36 | func (addr *ETHAddress) String() string { 37 | return addr.address 38 | } 39 | 40 | func (addr ETHAddress) MarshalJSON() ([]byte, error) { 41 | if err := validateAddress(addr.address); err != nil { 42 | return []byte{}, err 43 | } 44 | 45 | return json.Marshal(addr.address) 46 | } 47 | 48 | // UnmarshalJSON needs to be able to parse ETHAddress from both hex string or number 49 | func (addr *ETHAddress) UnmarshalJSON(data []byte) (err error) { 50 | asString := string(data) 51 | if strings.HasPrefix(asString, `"`) && strings.HasSuffix(asString, `"`) { 52 | asString = asString[1 : len(asString)-1] 53 | } 54 | if err := validateAddress(asString); err != nil { 55 | return err 56 | } 57 | 58 | addr.address = asString 59 | return nil 60 | } 61 | 62 | func validateAddress(address string) error { 63 | if !strings.HasPrefix(address, "0x") { 64 | return ErrNoHexPrefix 65 | } 66 | 67 | if len(address) != 42 { 68 | return ErrInvalidLength 69 | } 70 | 71 | _, err := hexutil.Decode(address) 72 | if err != nil { 73 | return errors.Wrap(err, "Invalid hexadecimal") 74 | } 75 | 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /playground/contracts/openzeppelin-solidity/contracts/ownership/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | /** 5 | * @title Ownable 6 | * @dev The Ownable contract has an owner address, and provides basic authorization control 7 | * functions, this simplifies the implementation of "user permissions". 8 | */ 9 | contract Ownable { 10 | address public owner; 11 | 12 | 13 | event OwnershipRenounced(address indexed previousOwner); 14 | event OwnershipTransferred( 15 | address indexed previousOwner, 16 | address indexed newOwner 17 | ); 18 | 19 | 20 | /** 21 | * @dev The Ownable constructor sets the original `owner` of the contract to the sender 22 | * account. 23 | */ 24 | constructor() public { 25 | owner = msg.sender; 26 | } 27 | 28 | /** 29 | * @dev Throws if called by any account other than the owner. 30 | */ 31 | modifier onlyOwner() { 32 | require(msg.sender == owner); 33 | _; 34 | } 35 | 36 | /** 37 | * @dev Allows the current owner to relinquish control of the contract. 38 | * @notice Renouncing to ownership will leave the contract without an owner. 39 | * It will not be possible to call the functions with the `onlyOwner` 40 | * modifier anymore. 41 | */ 42 | function renounceOwnership() public onlyOwner { 43 | emit OwnershipRenounced(owner); 44 | owner = address(0); 45 | } 46 | 47 | /** 48 | * @dev Allows the current owner to transfer control of the contract to a newOwner. 49 | * @param _newOwner The address to transfer ownership to. 50 | */ 51 | function transferOwnership(address _newOwner) public onlyOwner { 52 | _transferOwnership(_newOwner); 53 | } 54 | 55 | /** 56 | * @dev Transfers control of the contract to a newOwner. 57 | * @param _newOwner The address to transfer ownership to. 58 | */ 59 | function _transferOwnership(address _newOwner) internal { 60 | require(_newOwner != address(0)); 61 | emit OwnershipTransferred(owner, _newOwner); 62 | owner = _newOwner; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/transformer/eth_getBlockByNumber_test.go: -------------------------------------------------------------------------------- 1 | package transformer 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/qtumproject/janus/pkg/eth" 8 | "github.com/qtumproject/janus/pkg/internal" 9 | "github.com/qtumproject/janus/pkg/qtum" 10 | ) 11 | 12 | func initializeProxyETHGetBlockByNumber(qtumClient *qtum.Qtum) ETHProxy { 13 | return &ProxyETHGetBlockByNumber{qtumClient} 14 | } 15 | 16 | func TestGetBlockByNumberRequest(t *testing.T) { 17 | testETHProxyRequest( 18 | t, 19 | initializeProxyETHGetBlockByNumber, 20 | []json.RawMessage{[]byte(`"` + internal.GetTransactionByHashBlockNumberHex + `"`), []byte(`false`)}, 21 | &internal.GetTransactionByHashResponse, 22 | ) 23 | } 24 | 25 | func TestGetBlockByNumberWithTransactionsRequest(t *testing.T) { 26 | testETHProxyRequest( 27 | t, 28 | initializeProxyETHGetBlockByNumber, 29 | []json.RawMessage{[]byte(`"` + internal.GetTransactionByHashBlockNumberHex + `"`), []byte(`true`)}, 30 | &internal.GetTransactionByHashResponseWithTransactions, 31 | ) 32 | } 33 | 34 | func TestGetBlockByNumberUnknownBlockRequest(t *testing.T) { 35 | requestParams := []json.RawMessage{[]byte(`"` + internal.GetTransactionByHashBlockNumberHex + `"`), []byte(`true`)} 36 | request, err := internal.PrepareEthRPCRequest(1, requestParams) 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | 41 | mockedClientDoer := internal.NewDoerMappedMock() 42 | qtumClient, err := internal.CreateMockedClient(mockedClientDoer) 43 | 44 | unknownBlockResponse := qtum.GetErrorResponse(qtum.ErrInvalidParameter) 45 | err = mockedClientDoer.AddError(qtum.MethodGetBlockHash, unknownBlockResponse) 46 | if err != nil { 47 | t.Fatal(err) 48 | } 49 | 50 | //preparing proxy & executing request 51 | proxyEth := ProxyETHGetBlockByNumber{qtumClient} 52 | got, jsonErr := proxyEth.Request(request, internal.NewEchoContext()) 53 | if jsonErr != nil { 54 | t.Fatal(jsonErr) 55 | } 56 | 57 | want := (*eth.GetBlockByNumberResponse)(nil) 58 | 59 | internal.CheckTestResultDefault(want, got, t, false) 60 | } 61 | -------------------------------------------------------------------------------- /testing/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build build-openzeppelin openzeppelin 2 | build: build-openzeppelin 3 | 4 | # Build openzeppelin docker files with docker-compose 5 | openzeppelin-docker-compose: 6 | cd openzeppelin && ./run-openzeppelin-tests.sh 7 | 8 | build-openzeppelin: build-truffle-parser-docker build-openzeppelin-docker 9 | 10 | build-truffle-parser-docker: 11 | docker build -t qtum/janus-truffle-parser -f ./truffle-parser.Dockerfile . 12 | 13 | build-openzeppelin-docker: 14 | cd openzeppelin && docker build -t qtum/janus-openzeppelin -f ./openzeppelin.Dockerfile . 15 | 16 | init: 17 | git submodule init 18 | git submodule update 19 | cd openzeppelin/openzeppelin-contracts && yarn install 20 | cd openzeppelin/openzeppelin-contracts && yarn add mocha-spec-json-output-reporter 21 | 22 | openzeppelin: 23 | cd openzeppelin/openzeppelin-contracts && truffle test --network testing 24 | 25 | openzeppelin-development: 26 | cd openzeppelin/openzeppelin-contracts && truffle test --network development 27 | 28 | openzeppelin-docker: build 29 | docker run --rm qtum/janus-openzeppelin 30 | 31 | github-action-openzeppelin: 32 | docker logs ci_openzeppelin_1 | sed -n 's/.* \([0-9]\{1,\}\) passing.*/::set-output name=PASSING=::\1/p' 33 | docker logs ci_openzeppelin_1 | sed -n 's/.* \([0-9]\{1,\}\) pending.*/::set-output name=PENDING=::\1/p' 34 | docker logs ci_openzeppelin_1 | sed -n 's/.* \([0-9]\{1,\}\) failing.*/::set-output name=FAILING=::\1/p' 35 | 36 | openzeppelin-truffle-parser-docker: 37 | cd openzeppelin && make -f ../Makefile truffle-parser-docker 38 | 39 | truffle-parser-extract-result-docker: 40 | docker cp ${CONTAINER}:${INPUT} ./truffle-result-output.json 41 | 42 | truffle-parser-docker: 43 | echo ================================== 44 | cat ./truffle-result-output.json 45 | echo ================================== 46 | docker run --rm -v `pwd`:/output qtum/janus-truffle-parser \ 47 | --expected /output/truffle-expected-output.json \ 48 | --input /output/truffle-result-output.json \ 49 | --output /output/truffle-pruned-output.json -------------------------------------------------------------------------------- /pkg/eth/eth.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | var EmptyLogsBloom = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 8 | var DefaultSha3Uncles = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" 9 | 10 | const ( 11 | RPCVersion = "2.0" 12 | ) 13 | 14 | type JSONRPCRequest struct { 15 | JSONRPC string `json:"jsonrpc"` 16 | Method string `json:"method"` 17 | ID json.RawMessage `json:"id"` 18 | Params json.RawMessage `json:"params"` 19 | } 20 | 21 | type JSONRPCResult struct { 22 | JSONRPC string `json:"jsonrpc"` 23 | RawResult json.RawMessage `json:"result,omitempty"` 24 | Error JSONRPCError `json:"error,omitempty"` 25 | ID json.RawMessage `json:"id,omitempty"` 26 | } 27 | 28 | func NewJSONRPCResult(id json.RawMessage, res interface{}) (*JSONRPCResult, error) { 29 | rawResult, err := json.Marshal(res) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | return &JSONRPCResult{ 35 | JSONRPC: RPCVersion, 36 | ID: id, 37 | RawResult: rawResult, 38 | }, nil 39 | } 40 | 41 | type JSONRPCNotification struct { 42 | JSONRPC string `json:"jsonrpc"` 43 | Method string `json:"method,omitempty"` 44 | Params json.RawMessage `json:"params"` 45 | } 46 | 47 | func NewJSONRPCNotification(method string, params interface{}) (*JSONRPCNotification, error) { 48 | rawParams, err := json.Marshal(params) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | return &JSONRPCNotification{ 54 | JSONRPC: RPCVersion, 55 | Method: method, 56 | Params: rawParams, 57 | }, nil 58 | } 59 | -------------------------------------------------------------------------------- /playground/test/truffle-test-simpleStore.js: -------------------------------------------------------------------------------- 1 | /*const artifacts = require('./build/contracts/SimpleStore.json'); 2 | const contract = require('truffle-contract');*/ 3 | const SimpleStore = artifacts.require("SimpleStore"); 4 | 5 | contract("SimpleStore", async accounts => { 6 | 7 | it("Has been deployed", async () => { 8 | const simpleStoreDeployed = await SimpleStore.deployed(); 9 | assert(simpleStoreDeployed, "contract has been deployed"); 10 | console.log("Address is: ", simpleStoreDeployed.address) 11 | }); 12 | 13 | it("should return 100", async () => { 14 | const instance = await SimpleStore.deployed(); 15 | console.log("executing: get(): "); 16 | const balance = await instance.get(); 17 | assert.equal(balance.toNumber(), 100); 18 | console.log("value: ", balance.toNumber()) 19 | }); 20 | 21 | it("should return 184", async () => { 22 | const instance = await SimpleStore.deployed(); 23 | console.log("executing: set(150): "); 24 | await instance.set(184).then((receipt) => { console.log("receipt: ", receipt)}); 25 | const balance = await instance.get(); 26 | assert.equal(balance.toNumber(), 184); 27 | console.log("value: ", balance.toNumber()) 28 | 29 | 30 | }) 31 | 32 | 33 | }); 34 | /* 35 | function testGet(store) { 36 | return store.get().then(function(res) { 37 | console.log("exec: store.get()") 38 | console.log("value: ", res.toNumber()); 39 | }) 40 | } 41 | 42 | function testSet(store) { 43 | var newVal = Math.floor((Math.random() * 1000) + 1); 44 | console.log(`exec: store.set(${newVal})`) 45 | return store.set(newVal, {from: "0x7926223070547d2d15b2ef5e7383e541c338ffe9"}).then(function(res) { 46 | console.log("receipt: ", res) 47 | }).catch(function(e) { 48 | console.log(e) 49 | }) 50 | } 51 | 52 | var store; 53 | SimpleStore.deployed().then(function(i) { 54 | store = i; 55 | }).then(function() { 56 | return testGet(store) 57 | }).then(function() { 58 | return testSet(store) 59 | }).then(function() { 60 | return testGet(store) 61 | }).catch(function(e) { 62 | console.log(e) 63 | })*/ 64 | -------------------------------------------------------------------------------- /metamask/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 2 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation.
8 |