From ebec83c70458acef756264aade1a2f596663383a Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Thu, 1 Mar 2018 17:52:17 +0200 Subject: [PATCH 01/32] [Fix #339] Update GitHub comment in deploy-pending-contracts scheduler thread; refactor contract deployment code to a separate fn; remove unused code --- resources/sql/queries.sql | 19 ++++------------- src/clj/commiteth/bounties.clj | 38 +++++++++++++++++---------------- src/clj/commiteth/db/issues.clj | 6 ------ src/clj/commiteth/scheduler.clj | 30 ++++++-------------------- 4 files changed, 30 insertions(+), 63 deletions(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 1421ced..2335e72 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -196,20 +196,6 @@ AND i.contract_address IS NULL AND i.transaction_hash IS NOT NULL; --- :name list-failed-deployments :? :* --- :doc retrieves failed contract deployments -SELECT - i.issue_id as issue_id, - i.transaction_hash as transaction_hash, - u.address as owner_address -FROM issues i, users u, repositories r -WHERE r.user_id = u.id -AND i.repo_id = r.repo_id -AND i.contract_address IS NULL -AND i.transaction_hash IS NOT NULL -AND i.updated < now() at time zone 'UTC' - interval '1 hour'; - - -- Pull Requests ------------------------------------------------------------------- -- :name save-pull-request! :! :n @@ -252,7 +238,10 @@ WHERE pr_id = :pr_id; -- :doc bounty issues where deploy contract has failed SELECT i.issue_id AS issue_id, - u.address AS owner_address + i.issue_number AS issue_number, + u.login AS owner, + u.address AS owner_address, + r.repo AS repo FROM issues i, users u, repositories r WHERE r.user_id = u.id diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index 19d995b..aa2e04c 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -20,6 +20,25 @@ (let [labels (:labels issue)] (some #(= label-name (:name %)) labels))) +(defn deploy-contract [owner owner-address repo issue-id issue-number] + (if (empty? owner-address) + (log/error "Unable to deploy bounty contract because" + "repo owner has no Ethereum addres") + (do + (log/info "deploying contract to " owner-address) + (if-let [transaction-hash (multisig/deploy-multisig owner-address)] + (do + (log/info "Contract deployed, transaction-hash:" + transaction-hash) + (->> (github/post-deploying-comment owner + repo + issue-number + transaction-hash) + :id + (issues/update-comment-id issue-id)) + (issues/update-transaction-hash issue-id transaction-hash)) + (log/error "Failed to deploy contract to" owner-address))))) + (defn add-bounty-for-issue [repo repo-id issue] (let [{issue-id :id issue-number :number @@ -29,24 +48,7 @@ owner :owner} (users/get-repo-owner repo-id)] (log/debug "Adding bounty for issue " repo issue-number "owner address: " owner-address) (if (= 1 created-issue) - (if (empty? owner-address) - (log/error "Unable to deploy bounty contract because" - "repo owner has no Ethereum addres") - (do - (log/debug "deploying contract to " owner-address) - (let [transaction-hash (multisig/deploy-multisig owner-address)] - (if (nil? transaction-hash) - (log/error "Failed to deploy contract to" owner-address) - (do - (log/info "Contract deployed, transaction-hash:" - transaction-hash) - (->> (github/post-deploying-comment owner - repo - issue-number - transaction-hash) - :id - (issues/update-comment-id issue-id)))) - (issues/update-transaction-hash issue-id transaction-hash)))) + (deploy-contract owner owner-address repo issue-id issue-number) (log/debug "Issue already exists in DB, ignoring")))) (defn maybe-add-bounty-for-issue [repo repo-id issue] diff --git a/src/clj/commiteth/db/issues.clj b/src/clj/commiteth/db/issues.clj index 834684f..37db8d1 100644 --- a/src/clj/commiteth/db/issues.clj +++ b/src/clj/commiteth/db/issues.clj @@ -63,12 +63,6 @@ (jdbc/with-db-connection [con-db *db*] (db/list-pending-deployments con-db))) - -(defn list-failed-deployments - [] - (jdbc/with-db-connection [con-db *db*] - (db/list-failed-deployments con-db))) - (defn update-eth-balance [contract-address balance-eth] (jdbc/with-db-connection [con-db *db*] diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 0c35df3..f1535c7 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -54,33 +54,16 @@ (log/error "Failed to find contract address in tx logs"))))) -(defn deploy-contract [owner-address issue-id] - (let [transaction-hash (multisig/deploy-multisig owner-address)] - (if (nil? transaction-hash) - (log/error "Failed to deploy contract to" owner-address) - (log/info "Contract deployed, transaction-hash:" - transaction-hash )) - (issues/update-transaction-hash issue-id transaction-hash))) - - -(defn redeploy-failed-contracts - "If the bot account runs out of gas, we end up with transaction-id in db, but with nothing written to blockchain. In this case we should try to re-deploy the contract." - [] - (doseq [{issue-id :issue_id - transaction-hash :transaction_hash - owner-address :owner_address} (issues/list-failed-deployments)] - (when (nil? (eth/get-transaction-receipt transaction-hash)) - (log/info "Detected nil transaction receipt for pending contract deployment for issue" issue-id ", re-deploying contract") - (deploy-contract owner-address issue-id)))) - - (defn deploy-pending-contracts "Under high-concurrency circumstances or in case geth is in defunct state, a bounty contract may not deploy successfully when the bounty label is addded to an issue. This function deploys such contracts." [] (doseq [{issue-id :issue_id - owner-address :owner_address} (db-bounties/pending-contracts)] + issue-number :issue_number + owner :owner + owner-address :owner_address + repo :repo} (db-bounties/pending-contracts)] (log/debug "Trying to re-deploy failed bounty contract deployment, issue-id:" issue-id) - (deploy-contract owner-address issue-id))) + (bounties/deploy-contract owner owner-address repo issue-id issue-number))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" @@ -327,8 +310,7 @@ ;; TODO: disabled for now. looks like it may cause extraneus ;; contract deployments and costs (run-tasks - [;;redeploy-failed-contracts - deploy-pending-contracts + [deploy-pending-contracts update-issue-contract-address update-confirm-hash update-payout-receipt From 8c44e101287df39c913df916acde098ccf9c8651 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Fri, 16 Mar 2018 17:40:31 +0200 Subject: [PATCH 02/32] Add some logging for GitHub comment posting --- src/clj/commiteth/bounties.clj | 13 +++++++------ src/clj/commiteth/github/core.clj | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index aa2e04c..d911e6c 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -30,12 +30,13 @@ (do (log/info "Contract deployed, transaction-hash:" transaction-hash) - (->> (github/post-deploying-comment owner - repo - issue-number - transaction-hash) - :id - (issues/update-comment-id issue-id)) + (let [resp (github/post-deploying-comment owner + repo + issue-number + transaction-hash) + _ (log/info "post-deploying-comment response:" resp) + comment-id (:id resp)] + (issues/update-comment-id issue-id comment-id)) (issues/update-transaction-hash issue-id transaction-hash)) (log/error "Failed to deploy contract to" owner-address))))) diff --git a/src/clj/commiteth/github/core.clj b/src/clj/commiteth/github/core.clj index f6b4ea9..fafb577 100644 --- a/src/clj/commiteth/github/core.clj +++ b/src/clj/commiteth/github/core.clj @@ -272,7 +272,7 @@ (defn post-deploying-comment [owner repo issue-number tx-id] (let [comment (generate-deploying-comment owner repo issue-number tx-id)] - (log/debug "Posting comment to" (str owner "/" repo "/" issue-number) ":" comment) + (log/info "Posting comment to" (str owner "/" repo "/" issue-number) ":" comment) (issues/create-comment owner repo issue-number comment (self-auth-params)))) (defn make-patch-request [end-point positional query] From b833cee66dfbd98b46d2032abba41256202658d2 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 12:46:14 +0100 Subject: [PATCH 03/32] throw if eth-rpc returns error --- src/clj/commiteth/eth/core.clj | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index cd9ecfc..8f45808 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -127,13 +127,17 @@ result (safe-read-str (:body response))] (log/debug body "\n" result) - (if (= (:id result) request-id) - (:result result) - (do - (log/error "Geth returned an invalid json-rpc request ID," - "ignoring response") - (when-let [error (:error result)] - (log/error "Method: " method ", error: " error)))))) + (cond + ;; Ignore any responses that have mismatching request ID + (not= (:id result) request-id) + (log/error "Geth returned an invalid json-rpc request ID, ignoring response") + + ;; If request ID matches but contains error, throw + (:error result) + (throw (ex-info "Error submitting transaction via eth-rpc" (:error result))) + + :else + (:result result)))) (defn hex->big-integer [hex] From 4734a2e82ec2e5d80d48435f5f20cc1bbc4dc024 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Thu, 22 Mar 2018 13:17:30 +0200 Subject: [PATCH 04/32] Fix pending-contracts query to return proper repo owner --- resources/sql/queries.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index dbe24c3..27f5d68 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -236,7 +236,7 @@ WHERE pr_id = :pr_id; SELECT i.issue_id AS issue_id, i.issue_number AS issue_number, - u.login AS owner, + r.owner AS owner, u.address AS owner_address, r.repo AS repo FROM issues i, users u, repositories r From 595fd3bd83dd3d0bec59ec82a6d8ae083e8d2f1f Mon Sep 17 00:00:00 2001 From: Tetiana Churikova Date: Fri, 23 Mar 2018 13:39:49 +0200 Subject: [PATCH 05/32] Update core_testing_workflow.md --- doc/core_testing_workflow.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/core_testing_workflow.md b/doc/core_testing_workflow.md index 55c54c9..fc98cc6 100644 --- a/doc/core_testing_workflow.md +++ b/doc/core_testing_workflow.md @@ -6,14 +6,17 @@ How to test PR? Steps below could help a bit! ### Prerequisites Requirements for PRs to be tested: * should be in `To test` column in `Pipeline For Pull Requests` project +* should be updated to last develop. If button `Update` is avaivable on particular PR, click it and wait until it will be built. * shouldn't have conflicts with `develop` branch * should have a successful build in Jenkins [status-openbounty-app](https://jenkins.status.im/job/status-openbounty/job/status-openbounty-app/view/change-requests/) ### Deployment -In order to deploy feature to [testing env](https://testing.openbounty.status.im/) you should **rebuild** PR you are about to test. +In order to deploy feature to [testing env](https://testing.openbounty.status.im/) you should **rebuild** PR you are about to test (all open PRs are in [Jenkins](https://jenkins.status.im/job/status-openbounty/job/status-openbounty-app/view/change-requests/)). -Only one PR can be deployed on [testing env](https://testing.openbounty.status.im/) +When PR is successfully build and deployed, [testing env](https://testing.openbounty.status.im/) with deployed PR is accessible in 2-3 mins. + +Only one at one time PR can be deployed on [testing env](https://testing.openbounty.status.im/) Fresh develop branch with last changes is deployed automatically on [staging env](https://openbounty.status.im:444) @@ -21,7 +24,8 @@ Fresh develop branch with last changes is deployed automatically on [staging env 1) Move appropriate PR card to IN TESTING on the [Board](https://github.com/status-im/open-bounty/projects/3) and let people know you are on it - assign it to yourself! :) 2) Сheck the functionality current PR fixes / delivers (positive/negative tests related to the feature). In curtain cases it's worth to look in 'Files changed' tab in GitHub to check the list of what was changed to get understanding of the test coverage or "weak" places that have to be covered. Ask PR-author in #openbounty channel in slack what was changed if it's not clear from the notes in PR. 3) Check reasonable regression using [SOB-general test suite](https://ethstatus.testrail.net/index.php?/suites/view/27&group_by=cases:section_id&group_order=asc) -4) No issues? Perfect! Put appropriate label to the PR (`Tested - OK`), merge it to develop and move the PR instance to `Merged to develop`. -5) Found issues? Check for duplicates before adding one. Hint: make sure the issue is really introduced by current PR - check latest `develop` branch on [staging env](https://openbounty.status.im:444) . Issue exists in develop? Check existing issues list and make sure you are not adding duplicates before creating your own bug :) **All PR-specific issues should be added as comments to tested PR.** +4) No issues? Perfect! Put appropriate label to the PR (`Tested - OK`), merge it to develop (using `Rebase-Merge`) and move the PR instance to `Merged to develop`. +5) Found issues? Check for duplicates before adding one. Hint: make sure the issue is really introduced by current PR - check latest `develop` branch on [staging env](https://openbounty.status.im:444) . Issue exists in develop? Check existing issues list and make sure you are not adding duplicates before creating your own bug :) +**All PR-specific issues should be added as comments to tested PR.** Once all issues are logged put label `Tested-issues` to the PR and notify developer that there are several problems that are preventing the PR to merge. Move the PR to `Reviewing, waiting for contributor` on the board if PR is developed by external contributor, and to `Developing` - if it is presented by core contributor. From c111da4b9d1b9e02ffbcf0c8f42dfa899cc82efc Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 21 Mar 2018 17:52:29 +0100 Subject: [PATCH 06/32] fix #368: dont show `Manage Payouts` if user hasnt issued bounties --- src/cljs/commiteth/core.cljs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cljs/commiteth/core.cljs b/src/cljs/commiteth/core.cljs index 3e62083..62a27dd 100644 --- a/src/cljs/commiteth/core.cljs +++ b/src/cljs/commiteth/core.cljs @@ -74,19 +74,17 @@ (defn tabs [mobile?] (let [user (rf/subscribe [:user]) + owner-bounties (rf/subscribe [:owner-bounties]) current-page (rf/subscribe [:page])] - (fn [] - (let [tabs (apply conj [[:bounties (str (when-not @user "Open ") "Bounties")] - [:activity "Activity"]] - (when @user - [ - ;; NOTE(oskarth) Disabling this as repo management happens through GH app - #_[:repos "Repositories"] - [:manage-payouts (str (when-not mobile? "Manage ") "Payouts")] - (when (:status-team-member? @user) - [:usage-metrics "Usage metrics"])]))] + (fn tabs-render [] + (let [tabs [[:bounties (str (when-not @user "Open ") "Bounties")] + [:activity "Activity"] + (when (seq @owner-bounties) + [:manage-payouts (str (when-not mobile? "Manage ") "Payouts")]) + (when (:status-team-member? @user) + [:usage-metrics "Usage metrics"])]] (into [:div.ui.attached.tabular.menu.tiny] - (for [[page caption] tabs] + (for [[page caption] (remove nil? tabs)] (let [props {:class (str "ui item" (when (= @current-page page) " active")) :on-click #(commiteth.routes/nav! page)}] From 3465e66683959a971d09d6b20034d9954268fb44 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 19 Feb 2018 14:42:17 +0100 Subject: [PATCH 07/32] delete externs/web3-externs.js --- externs/web3-externs.js | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 externs/web3-externs.js diff --git a/externs/web3-externs.js b/externs/web3-externs.js deleted file mode 100644 index 4600afa..0000000 --- a/externs/web3-externs.js +++ /dev/null @@ -1,12 +0,0 @@ - -/* -externs for web3 injected into js context. needed for things to work with advanced cljs compilation - -TODO: probably not a good idea to maintain this manually in the long run*/ - -var web3 = { - eth: { - accounts: [], - sendTransaction: function() {} - } -}; From ec2f87e62151a2e55a66a67df14f740084555585 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 23 Mar 2018 13:52:15 +0100 Subject: [PATCH 08/32] access js/window.web3 in advanced-safe way --- src/cljs/commiteth/common.cljs | 4 ++++ src/cljs/commiteth/handlers.cljs | 5 +++-- src/cljs/commiteth/manage_payouts.cljs | 5 ++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cljs/commiteth/common.cljs b/src/cljs/commiteth/common.cljs index 60f6a31..7b87894 100644 --- a/src/cljs/commiteth/common.cljs +++ b/src/cljs/commiteth/common.cljs @@ -2,10 +2,14 @@ (:require [reagent.core :as r] [re-frame.core :as rf] [clojure.string :as str] + [goog.object :as gobj] [goog.date.relative] [goog.i18n.DateTimePatterns :as DateTimePatterns]) (:import (goog.i18n DateTimeFormat))) +(defn web3 [] + (gobj/get js/window "web3")) + (defn input [val-ratom props] (fn [] [:input diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index 65a7c0c..0f436dc 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -12,7 +12,8 @@ [akiroz.re-frame.storage :as rf-storage :refer [reg-co-fx!]] - [commiteth.ui-model :as ui-model])) + [commiteth.ui-model :as ui-model] + [commiteth.common :as common])) (rf-storage/reg-co-fx! :commiteth-sob {:fx :store @@ -49,7 +50,7 @@ (reg-event-fx :initialize-web3 (fn [{:keys [db]} [_]] - (let [injected-web3 (-> js/window .-web3) + (let [injected-web3 (common/web3) w3 (when (boolean injected-web3) (do (println "Using injected Web3 constructor with current provider") diff --git a/src/cljs/commiteth/manage_payouts.cljs b/src/cljs/commiteth/manage_payouts.cljs index a3272cc..32f4f06 100644 --- a/src/cljs/commiteth/manage_payouts.cljs +++ b/src/cljs/commiteth/manage_payouts.cljs @@ -78,10 +78,9 @@ [:container [:div.ui.active.inverted.dimmer [:div.ui.text.loader "Loading"]]] - (let [web3 (.-web3 js/window) - bounties (vals @owner-bounties)] + (let [bounties (vals @owner-bounties)] [:div.ui.container - (when (nil? web3) + (when (nil? (common/web3)) [:div.ui.warning.message [:i.warning.icon] "To sign off claims, please view Status Open Bounty in Status, Mist or Metamask"]) From ef4e1f411e860c8e16d04d42313b4da1e0f53eb5 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 21 Feb 2018 18:17:32 +0100 Subject: [PATCH 09/32] #300: add function which returns state of a given bounty --- resources/sql/queries.sql | 5 +++-- src/clj/commiteth/bounties.clj | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 27f5d68..4f866af 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -453,8 +453,9 @@ SELECT i.updated AS updated, i.winner_login AS winner_login, r.repo AS repo_name, - o.address AS owner_address -FROM issues i, users o, repositories r + o.address AS owner_address, + u.address AS payout_address +FROM users o, repositories r, issues i LEFT OUTER JOIN users u ON u.login = i.winner_login WHERE r.repo_id = i.repo_id AND r.user_id = o.id diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index d911e6c..3358015 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -105,3 +105,14 @@ (do (log/info "Updating changed title for issue" (:id gh-issue)) (issues/update-issue-title (:id gh-issue) (:title gh-issue))))))) + +(defn bounty-state [bounty] + (cond + (:payout_hash bounty) :paid + (nil? (:confirm_hash bounty)) :pending-maintainer-confirmation + (nil? (:payout_address bounty)) :pending-contributor-address + (:winner_login bounty) :merged + (some-> (:claim_count bounty) (< 1)) :multiple_claims + (= 1 (:claim_count bounty)) :claimed + (seq (:tokens bounty)) :funded + (:contract_address bounty) :opened)) From f654e0452fbd7e33593560200110208b306eab72 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 21 Feb 2018 18:36:21 +0100 Subject: [PATCH 10/32] #300: better guard around nil properties --- src/clj/commiteth/bounties.clj | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index 3358015..827f1c5 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -107,12 +107,14 @@ (issues/update-issue-title (:id gh-issue) (:title gh-issue))))))) (defn bounty-state [bounty] - (cond - (:payout_hash bounty) :paid - (nil? (:confirm_hash bounty)) :pending-maintainer-confirmation - (nil? (:payout_address bounty)) :pending-contributor-address - (:winner_login bounty) :merged - (some-> (:claim_count bounty) (< 1)) :multiple_claims - (= 1 (:claim_count bounty)) :claimed - (seq (:tokens bounty)) :funded - (:contract_address bounty) :opened)) + (if-let [merged? (:winner_login bounty)] + (cond + (nil? (:payout_address bounty)) :pending-contributor-address + (nil? (:confirm_hash bounty)) :pending-maintainer-confirmation + (:payout_hash bounty) :paid + :else :merged) + (cond ; not yet merged + (some-> (:claim_count bounty) (< 1)) :multiple_claims + (= 1 (:claim_count bounty)) :claimed + (seq (:tokens bounty)) :funded + (:contract_address bounty) :opened))) From 3db9266a32b8ed4d26237b9d9d573d4375473aef Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 22 Feb 2018 10:01:58 +0100 Subject: [PATCH 11/32] stash some development code --- src/clj/commiteth/bounties.clj | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index 827f1c5..c77a7d2 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -118,3 +118,31 @@ (= 1 (:claim_count bounty)) :claimed (seq (:tokens bounty)) :funded (:contract_address bounty) :opened))) + +(comment + (clojure.pprint/pprint + (bounties/get-bounty "martinklepsch" "RepoSOB" 28)) + + ;; STATES + ;; - tx submitted + ;; - waiting for contract to be mined + ;; - waiting for confirmation + ;; - confirmation received, etc. + (clojure.pprint/pprint + (bounties/closed-bounties)) + + (clojure.pprint/pprint + (count (bounties/owner-bounties 97496))) + + (clojure.pprint/pprint + (frequencies (map bounty-state (bounties/owner-bounties 97496)))) + + (clojure.pprint/pprint + (remove #(let [s (bounty-state %)] + (#{:paid :funded} s)) + (bounties/owner-bounties 97496))) + + + [:opened :funded :claimed (:claimed_multiple) ] + + ) From 35f9685fad9293dafa267cf73e5d0f22344c2648 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 22 Feb 2018 11:46:42 +0100 Subject: [PATCH 12/32] #300: clean up bounty-states, add docstring --- src/clj/commiteth/bounties.clj | 39 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index c77a7d2..d804131 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -106,43 +106,36 @@ (log/info "Updating changed title for issue" (:id gh-issue)) (issues/update-issue-title (:id gh-issue) (:title gh-issue))))))) -(defn bounty-state [bounty] +(defn bounty-state + "Given a map as returned by `owner-bounties` return the state the provided bounty is in. + + The lifecycle of a bounty is a sequence of the following states: + :opened > :funded > :claimed > :merged > :paid + + As well as various states that are only reached under specific conditins: + - :multiple-claims + - :pending-contributor-address + - :pending-maintainer-confirmation" + [bounty] (if-let [merged? (:winner_login bounty)] (cond (nil? (:payout_address bounty)) :pending-contributor-address (nil? (:confirm_hash bounty)) :pending-maintainer-confirmation (:payout_hash bounty) :paid - :else :merged) + :else :merged) (cond ; not yet merged - (some-> (:claim_count bounty) (< 1)) :multiple_claims + (some-> (:claim_count bounty) (< 1)) :multiple-claims (= 1 (:claim_count bounty)) :claimed (seq (:tokens bounty)) :funded (:contract_address bounty) :opened))) (comment - (clojure.pprint/pprint - (bounties/get-bounty "martinklepsch" "RepoSOB" 28)) - - ;; STATES - ;; - tx submitted - ;; - waiting for contract to be mined - ;; - waiting for confirmation - ;; - confirmation received, etc. - (clojure.pprint/pprint - (bounties/closed-bounties)) + (def user 97496) (clojure.pprint/pprint - (count (bounties/owner-bounties 97496))) + (count (bounties/owner-bounties user))) (clojure.pprint/pprint - (frequencies (map bounty-state (bounties/owner-bounties 97496)))) - - (clojure.pprint/pprint - (remove #(let [s (bounty-state %)] - (#{:paid :funded} s)) - (bounties/owner-bounties 97496))) - - - [:opened :funded :claimed (:claimed_multiple) ] + (frequencies (map bounty-state (bounties/owner-bounties user)))) ) From 21da4fb3b4368414f1b4b6b42aeb6fe1769e5974 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 28 Feb 2018 12:01:48 +0100 Subject: [PATCH 13/32] split user-bounties function into two --- src/clj/commiteth/routes/services.clj | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/clj/commiteth/routes/services.clj b/src/clj/commiteth/routes/services.clj index 5057eb5..8bb70db 100644 --- a/src/clj/commiteth/routes/services.clj +++ b/src/clj/commiteth/routes/services.clj @@ -61,18 +61,22 @@ github-repos)))) +(defn ^:private enrich-owner-bounties [owner-bounty] + (let [state (bounties/bounty-state owner-bounty) + claims (map + #(update % :value_usd usd-decimal->str) + (bounties-db/bounty-claims (:issue_id owner-bounty)))] + (-> owner-bounty + (update :value_usd usd-decimal->str) + (assoc :claims claims) + (assoc :state state)))) + (defn user-bounties [user] (let [owner-bounties (bounties-db/owner-bounties (:id user))] - (into {} - (for [ob owner-bounties - :let [b (update ob :value_usd usd-decimal->str)]] - [(:issue_id b) - (conj b - (let [claims (map - #(update % :value_usd usd-decimal->str) - (bounties-db/bounty-claims (:issue_id b)))] - {:claims claims}))])))) - + (->> owner-bounties + (map enrich-owner-bounties) + (map (juxt :issue_id identity)) + (into {})))) (defn top-hunters [] (let [renames {:user_name :display-name From 498f80c24a868f335b716a97e9c390161e8b8318 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 28 Feb 2018 12:02:13 +0100 Subject: [PATCH 14/32] assert that keys from enrichment process are present --- src/clj/commiteth/bounties.clj | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index d804131..13661ae 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -106,6 +106,11 @@ (log/info "Updating changed title for issue" (:id gh-issue)) (issues/update-issue-title (:id gh-issue) (:title gh-issue))))))) +(defn assert-keys [m ks] + (doseq [k ks] + (when-not (find m k) + (throw (ex-info (format "Expected key missing from provided map: %s" k) {:map m}))))) + (defn bounty-state "Given a map as returned by `owner-bounties` return the state the provided bounty is in. @@ -117,6 +122,8 @@ - :pending-contributor-address - :pending-maintainer-confirmation" [bounty] + (assert-keys bounty [:winner_login :payout_address :confirm_hash :payout_hash + :claims :tokens :contract_address]) (if-let [merged? (:winner_login bounty)] (cond (nil? (:payout_address bounty)) :pending-contributor-address @@ -124,10 +131,10 @@ (:payout_hash bounty) :paid :else :merged) (cond ; not yet merged - (some-> (:claim_count bounty) (< 1)) :multiple-claims - (= 1 (:claim_count bounty)) :claimed - (seq (:tokens bounty)) :funded - (:contract_address bounty) :opened))) + (< 1 (count (:claims bounty))) :multiple-claims + (= 1 (count (:claims bounty))) :claimed + (seq (:tokens bounty)) :funded + (:contract_address bounty) :opened))) (comment (def user 97496) From b7342ea0b97ee9dd09f820da081b2fc89ef52616 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 16 Mar 2018 17:20:39 +0100 Subject: [PATCH 15/32] fix exception related to missing :claims key --- src/clj/commiteth/routes/services.clj | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/clj/commiteth/routes/services.clj b/src/clj/commiteth/routes/services.clj index 8bb70db..ce5d426 100644 --- a/src/clj/commiteth/routes/services.clj +++ b/src/clj/commiteth/routes/services.clj @@ -62,14 +62,13 @@ (defn ^:private enrich-owner-bounties [owner-bounty] - (let [state (bounties/bounty-state owner-bounty) - claims (map - #(update % :value_usd usd-decimal->str) - (bounties-db/bounty-claims (:issue_id owner-bounty)))] - (-> owner-bounty + (let [claims (map + #(update % :value_usd usd-decimal->str) + (bounties-db/bounty-claims (:issue_id owner-bounty))) + with-claims (assoc owner-bounty :claims claims)] + (-> with-claims (update :value_usd usd-decimal->str) - (assoc :claims claims) - (assoc :state state)))) + (assoc :state (bounties/bounty-state with-claims))))) (defn user-bounties [user] (let [owner-bounties (bounties-db/owner-bounties (:id user))] From b9d2bb19390af49b6d1bcdde502d610c42a3cb7e Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Wed, 21 Feb 2018 10:55:27 -0500 Subject: [PATCH 16/32] upgrade clojure version to 1.9.0 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 4c18522..a89ee2b 100644 --- a/project.clj +++ b/project.clj @@ -9,7 +9,7 @@ [reagent-utils "0.2.1"] [reagent "0.7.0"] [org.clojure/clojurescript "1.9.946"] - [org.clojure/clojure "1.8.0"] + [org.clojure/clojure "1.9.0"] [selmer "1.11.1"] [com.taoensso/tufte "1.3.0"] [markdown-clj "1.0.1"] From 52d6eef292c1dae81de72274f9b85df1de54937c Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 11:17:28 +0100 Subject: [PATCH 17/32] fix failing DB test --- test/clj/commiteth/test/db/core.clj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/clj/commiteth/test/db/core.clj b/test/clj/commiteth/test/db/core.clj index 5d27e34..c45b777 100644 --- a/test/clj/commiteth/test/db/core.clj +++ b/test/clj/commiteth/test/db/core.clj @@ -34,5 +34,7 @@ :email nil :avatar_url "" :address "address" - :created nil} + :created nil + :welcome_email_sent 0 + :is_hidden_in_hunters false} (db/get-user t-conn {:id 1}))))) From 32c4d3ccee6133378e0dc0a42c35cb3dbb31dfef Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 12:46:35 +0100 Subject: [PATCH 18/32] disable contract deploy test since it requires gas --- test/clj/commiteth/test/multisig_wallet.clj | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/clj/commiteth/test/multisig_wallet.clj b/test/clj/commiteth/test/multisig_wallet.clj index 2858006..f1a80ba 100644 --- a/test/clj/commiteth/test/multisig_wallet.clj +++ b/test/clj/commiteth/test/multisig_wallet.clj @@ -17,12 +17,14 @@ (if (< (System/currentTimeMillis) end-time) (recur))))))) -;; deploys a multisig and gets it's address. assumes test environment configured correctly (access to running geth, eth wallet, password etc) +;; deploys a multisig and gets it's address +;; assumes test environment configured correctly +;; (eth wallet with some eth, password etc) (deftest test-deploy (testing "Deploying a multisig" - (let [tx-id (multisig/deploy-multisig OWNER_ADDRESS) - tx-receipt (wait-for (fn [] (eth/get-transaction-receipt tx-id))) - addr (-> tx-receipt - (multisig/find-created-multisig-address))] - (println "Created multisig address" addr) - (is (not-empty addr))))) + (println "WARN multisig deployment test currently disabled as it requires gas") + #_(let [tx-id (multisig/deploy-multisig OWNER_ADDRESS) + tx-receipt (wait-for (fn [] (eth/get-transaction-receipt tx-id))) + addr (multisig/find-created-multisig-address tx-receipt)] + (println "Created multisig address" addr) + (is (not-empty addr))))) From c599021a40e8a00d6cab0a17a3b1c1de5463f1ae Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 12 Mar 2018 23:49:28 +0700 Subject: [PATCH 19/32] include generated contract interfaces in git --- .gitignore | 1 - src/java/commiteth/eth/contracts/ERC20.java | 183 +++++ .../eth/contracts/MultiSigTokenWallet.java | 660 ++++++++++++++++++ src/java/commiteth/eth/contracts/Owned.java | 111 +++ .../commiteth/eth/contracts/TokenReg.java | 315 +++++++++ 5 files changed, 1269 insertions(+), 1 deletion(-) create mode 100644 src/java/commiteth/eth/contracts/ERC20.java create mode 100644 src/java/commiteth/eth/contracts/MultiSigTokenWallet.java create mode 100644 src/java/commiteth/eth/contracts/Owned.java create mode 100644 src/java/commiteth/eth/contracts/TokenReg.java diff --git a/.gitignore b/.gitignore index 39c20db..b57d8ab 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ node_modules /config-prod.edn /config-dev.edn /config-test.edn -/src/java diff --git a/src/java/commiteth/eth/contracts/ERC20.java b/src/java/commiteth/eth/contracts/ERC20.java new file mode 100644 index 0000000..87c61f6 --- /dev/null +++ b/src/java/commiteth/eth/contracts/ERC20.java @@ -0,0 +1,183 @@ +package commiteth.eth.contracts; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + * Auto generated code.
+ * Do not modify!
+ * Please use the web3j command line tools, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.3.0. + */ +public final class ERC20 extends Contract { + private static final String BINARY = ""; + + private ERC20(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private ERC20(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getTransferEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Transfer", + Arrays.>asList(new TypeReference

() {}, new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + TransferEventResponse typedResponse = new TransferEventResponse(); + typedResponse.from = (Address) eventValues.getIndexedValues().get(0); + typedResponse.to = (Address) eventValues.getIndexedValues().get(1); + typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable transferEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Transfer", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public TransferEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + TransferEventResponse typedResponse = new TransferEventResponse(); + typedResponse.from = (Address) eventValues.getIndexedValues().get(0); + typedResponse.to = (Address) eventValues.getIndexedValues().get(1); + typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getApprovalEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Approval", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + ApprovalEventResponse typedResponse = new ApprovalEventResponse(); + typedResponse.owner = (Address) eventValues.getIndexedValues().get(0); + typedResponse.spender = (Address) eventValues.getIndexedValues().get(1); + typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable approvalEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Approval", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public ApprovalEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + ApprovalEventResponse typedResponse = new ApprovalEventResponse(); + typedResponse.owner = (Address) eventValues.getIndexedValues().get(0); + typedResponse.spender = (Address) eventValues.getIndexedValues().get(1); + typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0); + return typedResponse; + } + }); + } + + public Future approve(Address spender, Uint256 value) { + Function function = new Function("approve", Arrays.asList(spender, value), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future totalSupply() { + Function function = new Function("totalSupply", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future transferFrom(Address from, Address to, Uint256 value) { + Function function = new Function("transferFrom", Arrays.asList(from, to, value), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future balanceOf(Address who) { + Function function = new Function("balanceOf", + Arrays.asList(who), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future transfer(Address to, Uint256 value) { + Function function = new Function("transfer", Arrays.asList(to, value), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future allowance(Address owner, Address spender) { + Function function = new Function("allowance", + Arrays.asList(owner, spender), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(ERC20.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(ERC20.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new ERC20(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new ERC20(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class TransferEventResponse { + public Address from; + + public Address to; + + public Uint256 value; + } + + public static class ApprovalEventResponse { + public Address owner; + + public Address spender; + + public Uint256 value; + } +} diff --git a/src/java/commiteth/eth/contracts/MultiSigTokenWallet.java b/src/java/commiteth/eth/contracts/MultiSigTokenWallet.java new file mode 100644 index 0000000..21f9d79 --- /dev/null +++ b/src/java/commiteth/eth/contracts/MultiSigTokenWallet.java @@ -0,0 +1,660 @@ +package commiteth.eth.contracts; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + * Auto generated code.
+ * Do not modify!
+ * Please use the web3j command line tools, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.3.0. + */ +public final class MultiSigTokenWallet extends Contract { + private static final String BINARY = "6060604052341561000f57600080fd5b5b6127718061001f6000396000f300606060405236156101bc5763ffffffff60e060020a60003504166301e336678114610207578063025e7c2714610231578063173825d91461026357806320ea8d8614610284578063273cbaa01461029c5780632f54bf6e146103035780633411c81c14610336578063342b7e711461036c57806336756a23146103bd5780634f383934146104105780634f64b2be146104615780635143a9fe14610493578063523fba7f14610501578063547415251461053257806358e2cd76146105615780637065cb4814610582578063784547a7146105a35780638b51d13f146105cd5780638f4ffcb1146105f55780639ace38c214610663578063a0e67e2b14610722578063a878aee614610789578063a8abe69a146107aa578063affed0e014610821578063b5dc40c314610846578063b77bf600146108b0578063b97fd9e1146108d5578063ba51a6df146108f6578063c01a8c841461090e578063c0ee0b8a14610926578063c64274741461098d578063cd49952314610a04578063d74f8edd14610a42578063dc8452cd14610a67578063e20056e614610a8c578063e3004b5714610ab3578063ee22610b14610b14578063f750aaa614610b2c575b5b60003411156102045733600160a060020a03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405190815260200160405180910390a25b5b005b341561021257600080fd5b610204600160a060020a0360043581169060243516604435610b4d565b005b341561023c57600080fd5b610247600435610c5c565b604051600160a060020a03909116815260200160405180910390f35b341561026e57600080fd5b610204600160a060020a0360043516610c8e565b005b341561028f57600080fd5b610204600435610e43565b005b34156102a757600080fd5b6102af610f25565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156102ef5780820151818401525b6020016102d6565b505050509050019250505060405180910390f35b341561030e57600080fd5b610322600160a060020a0360043516610f8e565b604051901515815260200160405180910390f35b341561034157600080fd5b610322600435600160a060020a0360243516610fa3565b604051901515815260200160405180910390f35b341561037757600080fd5b6102046004602481358181019083013580602081810201604051908101604052809392919081815260200183836020028082843750949650610fc395505050505050565b005b34156103c857600080fd5b61020460046024813581810190830135806020818102016040519081016040528093929190818152602001838360200280828437509496505093359350610ffc92505050565b005b341561041b57600080fd5b610204600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061113a95505050505050565b005b341561046c57600080fd5b610247600435611168565b604051600160a060020a03909116815260200160405180910390f35b341561049e57600080fd5b61020460048035600160a060020a0390811691602480359260443516919060849060643590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061119a95505050505050565b005b341561050c57600080fd5b610520600160a060020a0360043516611270565b60405190815260200160405180910390f35b341561053d57600080fd5b61052060043515156024351515611282565b60405190815260200160405180910390f35b341561056c57600080fd5b610204600160a060020a03600435166112f1565b005b341561058d57600080fd5b610204600160a060020a03600435166113e0565b005b34156105ae57600080fd5b61032260043561151a565b604051901515815260200160405180910390f35b34156105d857600080fd5b6105206004356115ae565b60405190815260200160405180910390f35b341561060057600080fd5b61020460048035600160a060020a0390811691602480359260443516919060849060643590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061162d95505050505050565b005b341561066e57600080fd5b610679600435611640565b604051600160a060020a03851681526020810184905281151560608201526080604082018181528454600260001961010060018416150201909116049183018290529060a0830190859080156107105780601f106106e557610100808354040283529160200191610710565b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b50509550505050505060405180910390f35b341561072d57600080fd5b6102af611673565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156102ef5780820151818401525b6020016102d6565b505050509050019250505060405180910390f35b341561079457600080fd5b610204600160a060020a03600435166116dc565b005b34156107b557600080fd5b6102af60043560243560443515156064351515611911565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156102ef5780820151818401525b6020016102d6565b505050509050019250505060405180910390f35b341561082c57600080fd5b610520611a3f565b60405190815260200160405180910390f35b341561085157600080fd5b6102af600435611a45565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156102ef5780820151818401525b6020016102d6565b505050509050019250505060405180910390f35b34156108bb57600080fd5b610520611bc5565b60405190815260200160405180910390f35b34156108e057600080fd5b610204600160a060020a0360043516611bcb565b005b341561090157600080fd5b610204600435611ce1565b005b341561091957600080fd5b610204600435611d77565b005b341561093157600080fd5b61020460048035600160a060020a03169060248035919060649060443590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650611e6895505050505050565b005b341561099857600080fd5b61052060048035600160a060020a03169060248035919060649060443590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650611e7a95505050505050565b60405190815260200160405180910390f35b3415610a0f57600080fd5b610247600160a060020a0360043516602435611e9a565b604051600160a060020a03909116815260200160405180910390f35b3415610a4d57600080fd5b610520611edc565b60405190815260200160405180910390f35b3415610a7257600080fd5b610520611ee1565b60405190815260200160405180910390f35b3415610a9757600080fd5b610204600160a060020a0360043581169060243516611ee7565b005b3415610abe57600080fd5b61020460048035600160a060020a03169060446024803590810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496506120a895505050505050565b005b3415610b1f57600080fd5b610204600435612139565b005b3415610b3757600080fd5b610204600160a060020a036004351661229a565b005b60008083600160a060020a0381161515610b6657600080fd5b30600160a060020a031633600160a060020a0316141515610b8657600080fd5b60008411610b9357600080fd5b600160a060020a038616600090815260056020526040902054925082841115610bbb57600080fd5b600160a060020a038616600081815260056020526040808220878703905563a9059cbb918891889190516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b1515610c2c57600080fd5b6102c65a03f11515610c3d57600080fd5b5050506040518051925050811515610c5157fe5b5b5b5b505050505050565b6000805482908110610c6a57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b60008030600160a060020a031633600160a060020a0316141515610cb157600080fd5b600160a060020a038316600090815260066020526040902054839060ff161515610cda57600080fd5b600160a060020a0384166000908152600660205260408120805460ff19169055805460001901935091505b82821015610dd75783600160a060020a0316600083815481101515610d2657fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600160a060020a03161415610dcb57600080546000198101908110610d6757fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600083815481101515610d9657fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a03160217905550610dd7565b5b600190910190610d05565b600080546000190190610dea9082612580565b506000546008541115610e0357600054610e0390611ce1565b5b83600160a060020a03167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a25b5b505b505050565b33600160a060020a03811660009081526006602052604090205460ff161515610e6b57600080fd5b600082815260036020908152604080832033600160a060020a038116855292529091205483919060ff161515610ea057600080fd5b600084815260026020526040902060030154849060ff1615610ec157600080fd5b6000858152600360209081526040808320600160a060020a033316808552925291829020805460ff1916905586917ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e9905160405180910390a35b5b505b50505b5050565b610f2d6125aa565b6001805480602002602001604051908101604052809291908181526020018280548015610f8357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f65575b505050505090505b90565b60066020526000908152604090205460ff1681565b600360209081526000928352604080842090915290825290205460ff1681565b30600160a060020a031633600160a060020a0316141515610fe357600080fd5b6001818051610f219291602001906125bc565b505b5b50565b6000825182603282111580156110125750818111155b801561101d57508015155b801561102857508115155b151561103357600080fd5b6000541580156110435750600854155b151561104e57600080fd5b600092505b8451831015611118576006600086858151811061106c57fe5b90602001906020020151600160a060020a0316815260208101919091526040016000205460ff161580156110bd57508483815181106110a757fe5b90602001906020020151600160a060020a031615155b15156110c857600080fd5b6001600660008786815181106110da57fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600190920191611053565b600085805161112b9291602001906125bc565b5060088490555b5b5050505050565b600160a060020a0333166000908152600760205260409020818051610f219291602001906125bc565b505b50565b6001805482908110610c6a57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b60008030600160a060020a031686600160a060020a031614156111bc57610c51565b600954915083600160a060020a03166323b872dd87308860006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561122b57600080fd5b6102c65a03f1151561123c57600080fd5b505050604051805191505080151561125057fe5b816009541415610c5157610c518686868661231d565b5b5b505050505050565b60056020526000908152604090205481565b6000805b6004548110156112e9578380156112af575060008181526002602052604090206003015460ff16155b806112d357508280156112d3575060008181526002602052604090206003015460ff165b5b156112e0576001820191505b5b600101611286565b5b5092915050565b33600160a060020a0381166000908152600660205260408120549091829160ff16151561131d57600080fd5b600160a060020a0384166000818152600560205260408082205495506370a08231913091516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561138457600080fd5b6102c65a03f1151561139557600080fd5b505050604051805192505082821115610e3b57610e3b60008484038660006040518059106113c05750595b908082528060200260200182016040525b5061231d565b5b5b5b50505050565b30600160a060020a031633600160a060020a031614151561140057600080fd5b600160a060020a038116600090815260066020526040902054819060ff161561142857600080fd5b81600160a060020a038116151561143e57600080fd5b6000805490506001016008546032821115801561145b5750818111155b801561146657508015155b801561147157508115155b151561147c57600080fd5b600160a060020a0385166000908152600660205260408120805460ff1916600190811790915581549081016114b18382612580565b916000526020600020900160005b8154600160a060020a03808a166101009390930a8381029102199091161790915590507ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b50505b505b505b50565b600080805b6000548110156115a6576000848152600360205260408120815490919081908490811061154857fe5b906000526020600020900160005b9054600160a060020a036101009290920a900416815260208101919091526040016000205460ff161561158a576001820191505b60085482141561159d57600192506115a6565b5b60010161151f565b5b5050919050565b6000805b60005481101561162657600083815260036020526040812081549091908190849081106115db57fe5b906000526020600020900160005b9054600160a060020a036101009290920a900416815260208101919091526040016000205460ff161561161d576001820191505b5b6001016115b2565b5b50919050565b610e3b8484848461119a565b5b50505050565b6002602081905260009182526040909120805460018201546003830154600160a060020a03909216939092019060ff1684565b61167b6125aa565b6000805480602002602001604051908101604052809291908181526020018280548015610f8357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f65575b505050505090505b90565b6116e46125aa565b600080808085600160a060020a03811615156116ff57600080fd5b30600160a060020a031633600160a060020a031614151561171f57600080fd5b600160a060020a03871660009081526007602052604081205411156117c3576007600088600160a060020a0316600160a060020a031681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156117b757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611799575b50505050509550611821565b600180548060200260200160405190810160405280929190818152602001828054801561181957602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116117fb575b505050505095505b85519450600093505b848410156119055785848151811061183e57fe5b90602001906020020151600160a060020a0381166000908152600560205260408120549194509092508211156118f957600160a060020a03831660008181526005602052604080822082905563a9059cbb918a91869190516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156118dd57600080fd5b6102c65a03f115156118ee57600080fd5b505050604051805150505b5b60019093019261182a565b5b5b5b50505050505050565b6119196125aa565b6119216125aa565b6000806004546040518059106119345750595b908082528060200260200182016040525b50925060009150600090505b6004548110156119cc5785801561197a575060008181526002602052604090206003015460ff16155b8061199e575084801561199e575060008181526002602052604090206003015460ff165b5b156119c357808383815181106119b157fe5b60209081029091010152600191909101905b5b600101611951565b8787036040518059106119dc5750595b908082528060200260200182016040525b5093508790505b86811015611a3357828181518110611a0857fe5b906020019060200201518489830381518110611a2057fe5b602090810290910101525b6001016119f4565b5b505050949350505050565b60095481565b611a4d6125aa565b611a556125aa565b600080548190604051805910611a685750595b908082528060200260200182016040525b50925060009150600090505b600054811015611b4b5760008581526003602052604081208154909190819084908110611aae57fe5b906000526020600020900160005b9054600160a060020a036101009290920a900416815260208101919091526040016000205460ff1615611b42576000805482908110611af757fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316838381518110611b2357fe5b600160a060020a03909216602092830290910190910152600191909101905b5b600101611a85565b81604051805910611b595750595b908082528060200260200182016040525b509350600090505b81811015611bbc57828181518110611b8657fe5b90602001906020020151848281518110611b9c57fe5b600160a060020a039092166020928302909101909101525b600101611b72565b5b505050919050565b60045481565b611bd36125aa565b60008083600160a060020a0381161515611bec57600080fd5b600160a060020a038516600090815260066020526040902054859060ff1615611c1457600080fd5b30600160a060020a031633600160a060020a0316141515611c3457600080fd5b6000805480602002602001604051908101604052809291908181526020018280548015611c8a57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611c6c575b5050505050945084519350611c9e866113e0565b600092505b83831015610c5157611cc9858481518110611cba57fe5b90602001906020020151610c8e565b5b600190920191611ca3565b5b5b5b505b5050505050565b30600160a060020a031633600160a060020a0316141515611d0157600080fd5b6000548160328211801590611d165750818111155b8015611d2157508015155b8015611d2c57508115155b1515611d3757600080fd5b60088390557fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a8360405190815260200160405180910390a15b5b50505b50565b33600160a060020a03811660009081526006602052604090205460ff161515611d9f57600080fd5b6000828152600260205260409020548290600160a060020a03161515611dc457600080fd5b600083815260036020908152604080832033600160a060020a038116855292529091205484919060ff1615611df857600080fd5b6000858152600360209081526040808320600160a060020a033316808552925291829020805460ff1916600117905586917f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef905160405180910390a3610f1b85612139565b5b5b50505b505b5050565b610e3e8383338461231d565b5b505050565b6000611e87848484612480565b9050611e9281611d77565b5b9392505050565b600760205281600052604060002081815481101515611eb557fe5b906000526020600020900160005b915091509054906101000a9004600160a060020a031681565b603281565b60085481565b600030600160a060020a031633600160a060020a0316141515611f0957600080fd5b600160a060020a038316600090815260066020526040902054839060ff161515611f3257600080fd5b600160a060020a038316600090815260066020526040902054839060ff1615611f5a57600080fd5b600092505b6000548310156120025784600160a060020a0316600084815481101515611f8257fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600160a060020a03161415611ff65783600084815481101515611fc157fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a03160217905550612002565b5b600190920191611f5f565b600160a060020a03808616600081815260066020526040808220805460ff199081169091559388168252908190208054909316600117909255907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b90905160405180910390a283600160a060020a03167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b505b505b505050565b336000600160a060020a03841663dd62ed3e8330846040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561210957600080fd5b6102c65a03f1151561211a57600080fd5b505050604051805190509050610e3b8282868661119a565b5b50505050565b600081815260026020526040812060030154829060ff161561215a57600080fd5b6121638361151a565b15610e3e5760008381526002602081905260409182902060038101805460ff19166001908117909155815490820154919550600160a060020a03169290918501905180828054600181600116156101000203166002900480156122075780601f106121dc57610100808354040283529160200191612207565b820191906000526020600020905b8154815290600101906020018083116121ea57829003601f168201915b505091505060006040518083038185876187965a03f1925050501561225857827f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2610e3e565b827f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260038201805460ff191690555b5b5b5b505050565b80600160a060020a03811615156122b057600080fd5b30600160a060020a031633600160a060020a03161415156122d057600080fd5b6122d9826116dc565b81600160a060020a03166108fc30600160a060020a0316319081150290604051600060405180830381858888f193505050501515610f2157600080fd5b5b5b5b5050565b83600160a060020a03167f98c09d9949722bae4bd0d988d4050091c3ae7ec6d51d3c6bbfe4233593944e9e8385604051600160a060020a03909216825260208201526040908101905180910390a2600980546001019055600160a060020a038216600090815260056020526040902054151561245a57600180548082016123a48382612580565b916000526020600020900160005b8154600160a060020a038087166101009390930a8381029102199091161790915590506370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561242257600080fd5b6102c65a03f1151561243357600080fd5b5050506040518051600160a060020a03841660009081526005602052604090205550610e3b565b600160a060020a03821660009081526005602052604090208054840190555b5b50505050565b600083600160a060020a038116151561249857600080fd5b600454915060806040519081016040908152600160a060020a038716825260208083018790528183018690526000606084018190528581526002909152208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03919091161781556020820151816001015560408201518160020190805161252492916020019061266d565b506060820151600391909101805460ff191691151591909117905550600480546001019055817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a25b5b509392505050565b815481835581811511610e3e57600083815260209020610e3e9181019083016126ec565b5b505050565b60206040519081016040526000815290565b828054828255906000526020600020908101928215612620579160200282015b82811115612620578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116178255602092909201916001909101906125dc565b5b5061262d92915061270d565b5090565b815481835581811511610e3e57600083815260209020610e3e9181019083016126ec565b5b505050565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106126ae57805160ff19168380011785556126db565b828001600101855582156126db579182015b828111156126db5782518255916020019190600101906126c0565b5b5061262d9291506126ec565b5090565b610f8b91905b8082111561262d57600081556001016126f2565b5090565b90565b610f8b91905b8082111561262d57805473ffffffffffffffffffffffffffffffffffffffff19168155600101612713565b5090565b905600a165627a7a723058200786c077331fb9b692c0f2a7255efbc0c5d18913e1e95b4e28e8fb5cc1d324930029"; + + private MultiSigTokenWallet(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private MultiSigTokenWallet(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getConfirmationEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Confirmation", + Arrays.>asList(new TypeReference

() {}, new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + ConfirmationEventResponse typedResponse = new ConfirmationEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable confirmationEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Confirmation", + Arrays.>asList(new TypeReference
() {}, new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public ConfirmationEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + ConfirmationEventResponse typedResponse = new ConfirmationEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(1); + return typedResponse; + } + }); + } + + public List getRevocationEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Revocation", + Arrays.>asList(new TypeReference
() {}, new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + RevocationEventResponse typedResponse = new RevocationEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable revocationEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Revocation", + Arrays.>asList(new TypeReference
() {}, new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public RevocationEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + RevocationEventResponse typedResponse = new RevocationEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(1); + return typedResponse; + } + }); + } + + public List getSubmissionEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Submission", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + SubmissionEventResponse typedResponse = new SubmissionEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable submissionEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Submission", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public SubmissionEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + SubmissionEventResponse typedResponse = new SubmissionEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getExecutionEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Execution", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + ExecutionEventResponse typedResponse = new ExecutionEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable executionEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Execution", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public ExecutionEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + ExecutionEventResponse typedResponse = new ExecutionEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getExecutionFailureEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("ExecutionFailure", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + ExecutionFailureEventResponse typedResponse = new ExecutionFailureEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable executionFailureEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("ExecutionFailure", + Arrays.>asList(new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public ExecutionFailureEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + ExecutionFailureEventResponse typedResponse = new ExecutionFailureEventResponse(); + typedResponse._transactionId = (Uint256) eventValues.getIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getDepositEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Deposit", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + DepositEventResponse typedResponse = new DepositEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable depositEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Deposit", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList(new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public DepositEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + DepositEventResponse typedResponse = new DepositEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getTokenDepositEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("TokenDeposit", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList(new TypeReference
() {}, new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + TokenDepositEventResponse typedResponse = new TokenDepositEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._token = (Address) eventValues.getNonIndexedValues().get(0); + typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable tokenDepositEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("TokenDeposit", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList(new TypeReference
() {}, new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public TokenDepositEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + TokenDepositEventResponse typedResponse = new TokenDepositEventResponse(); + typedResponse._sender = (Address) eventValues.getIndexedValues().get(0); + typedResponse._token = (Address) eventValues.getNonIndexedValues().get(0); + typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(1); + return typedResponse; + } + }); + } + + public List getOwnerAdditionEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("OwnerAddition", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + OwnerAdditionEventResponse typedResponse = new OwnerAdditionEventResponse(); + typedResponse._owner = (Address) eventValues.getIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable ownerAdditionEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("OwnerAddition", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public OwnerAdditionEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + OwnerAdditionEventResponse typedResponse = new OwnerAdditionEventResponse(); + typedResponse._owner = (Address) eventValues.getIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getOwnerRemovalEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("OwnerRemoval", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + OwnerRemovalEventResponse typedResponse = new OwnerRemovalEventResponse(); + typedResponse._owner = (Address) eventValues.getIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable ownerRemovalEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("OwnerRemoval", + Arrays.>asList(new TypeReference
() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public OwnerRemovalEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + OwnerRemovalEventResponse typedResponse = new OwnerRemovalEventResponse(); + typedResponse._owner = (Address) eventValues.getIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getRequirementChangeEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("RequirementChange", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + RequirementChangeEventResponse typedResponse = new RequirementChangeEventResponse(); + typedResponse._required = (Uint256) eventValues.getNonIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable requirementChangeEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("RequirementChange", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public RequirementChangeEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + RequirementChangeEventResponse typedResponse = new RequirementChangeEventResponse(); + typedResponse._required = (Uint256) eventValues.getNonIndexedValues().get(0); + return typedResponse; + } + }); + } + + public Future withdrawToken(Address _tokenAddr, Address _dest, Uint256 _amount) { + Function function = new Function("withdrawToken", Arrays.asList(_tokenAddr, _dest, _amount), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future
owners(Uint256 param0) { + Function function = new Function("owners", + Arrays.asList(param0), + Arrays.>asList(new TypeReference
() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future removeOwner(Address owner) { + Function function = new Function("removeOwner", Arrays.asList(owner), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future revokeConfirmation(Uint256 transactionId) { + Function function = new Function("revokeConfirmation", Arrays.asList(transactionId), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future> getTokenList() { + Function function = new Function("getTokenList", + Arrays.asList(), + Arrays.>asList(new TypeReference>() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future isOwner(Address param0) { + Function function = new Function("isOwner", + Arrays.asList(param0), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future confirmations(Uint256 param0, Address param1) { + Function function = new Function("confirmations", + Arrays.asList(param0, param1), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future setTokenList(DynamicArray
_tokenList) { + Function function = new Function("setTokenList", Arrays.asList(_tokenList), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future constructor(DynamicArray
_owners, Uint256 _required) { + Function function = new Function("constructor", Arrays.asList(_owners, _required), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future setMyTokenList(DynamicArray
_tokenList) { + Function function = new Function("setMyTokenList", Arrays.asList(_tokenList), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future
tokens(Uint256 param0) { + Function function = new Function("tokens", + Arrays.asList(param0), + Arrays.>asList(new TypeReference
() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future deposit(Address _from, Uint256 _amount, Address _token, DynamicBytes _data) { + Function function = new Function("deposit", Arrays.asList(_from, _amount, _token, _data), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future tokenBalances(Address param0) { + Function function = new Function("tokenBalances", + Arrays.asList(param0), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getTransactionCount(Bool pending, Bool executed) { + Function function = new Function("getTransactionCount", + Arrays.asList(pending, executed), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future watch(Address _tokenAddr) { + Function function = new Function("watch", Arrays.asList(_tokenAddr), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future addOwner(Address owner) { + Function function = new Function("addOwner", Arrays.asList(owner), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future isConfirmed(Uint256 transactionId) { + Function function = new Function("isConfirmed", + Arrays.asList(transactionId), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getConfirmationCount(Uint256 transactionId) { + Function function = new Function("getConfirmationCount", + Arrays.asList(transactionId), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future receiveApproval(Address _from, Uint256 _amount, Address _token, DynamicBytes _data) { + Function function = new Function("receiveApproval", Arrays.asList(_from, _amount, _token, _data), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future> transactions(Uint256 param0) { + Function function = new Function("transactions", + Arrays.asList(param0), + Arrays.>asList(new TypeReference
() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference() {})); + return executeCallMultipleValueReturnAsync(function); + } + + public Future> getOwners() { + Function function = new Function("getOwners", + Arrays.asList(), + Arrays.>asList(new TypeReference>() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future withdrawAllTokens(Address _dest) { + Function function = new Function("withdrawAllTokens", Arrays.asList(_dest), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future> getTransactionIds(Uint256 from, Uint256 to, Bool pending, Bool executed) { + Function function = new Function("getTransactionIds", + Arrays.asList(from, to, pending, executed), + Arrays.>asList(new TypeReference>() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future nonce() { + Function function = new Function("nonce", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future> getConfirmations(Uint256 transactionId) { + Function function = new Function("getConfirmations", + Arrays.asList(transactionId), + Arrays.>asList(new TypeReference>() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future transactionCount() { + Function function = new Function("transactionCount", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future releaseWallet(Address _dest) { + Function function = new Function("releaseWallet", Arrays.asList(_dest), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future changeRequirement(Uint256 _required) { + Function function = new Function("changeRequirement", Arrays.asList(_required), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future confirmTransaction(Uint256 transactionId) { + Function function = new Function("confirmTransaction", Arrays.asList(transactionId), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future tokenFallback(Address _from, Uint256 _amount, DynamicBytes _data) { + Function function = new Function("tokenFallback", Arrays.asList(_from, _amount, _data), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future submitTransaction(Address destination, Uint256 value, DynamicBytes data) { + Function function = new Function("submitTransaction", Arrays.asList(destination, value, data), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future
userList(Address param0, Uint256 param1) { + Function function = new Function("userList", + Arrays.asList(param0, param1), + Arrays.>asList(new TypeReference
() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future MAX_OWNER_COUNT() { + Function function = new Function("MAX_OWNER_COUNT", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future required() { + Function function = new Function("required", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future replaceOwner(Address owner, Address newOwner) { + Function function = new Function("replaceOwner", Arrays.asList(owner, newOwner), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future depositToken(Address _token, DynamicBytes _data) { + Function function = new Function("depositToken", Arrays.asList(_token, _data), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future executeTransaction(Uint256 transactionId) { + Function function = new Function("executeTransaction", Arrays.asList(transactionId), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future withdrawEverything(Address _dest) { + Function function = new Function("withdrawEverything", Arrays.asList(_dest), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(MultiSigTokenWallet.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(MultiSigTokenWallet.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static MultiSigTokenWallet load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new MultiSigTokenWallet(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static MultiSigTokenWallet load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new MultiSigTokenWallet(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class ConfirmationEventResponse { + public Address _sender; + + public Uint256 _transactionId; + } + + public static class RevocationEventResponse { + public Address _sender; + + public Uint256 _transactionId; + } + + public static class SubmissionEventResponse { + public Uint256 _transactionId; + } + + public static class ExecutionEventResponse { + public Uint256 _transactionId; + } + + public static class ExecutionFailureEventResponse { + public Uint256 _transactionId; + } + + public static class DepositEventResponse { + public Address _sender; + + public Uint256 _value; + } + + public static class TokenDepositEventResponse { + public Address _sender; + + public Address _token; + + public Uint256 _value; + } + + public static class OwnerAdditionEventResponse { + public Address _owner; + } + + public static class OwnerRemovalEventResponse { + public Address _owner; + } + + public static class RequirementChangeEventResponse { + public Uint256 _required; + } +} diff --git a/src/java/commiteth/eth/contracts/Owned.java b/src/java/commiteth/eth/contracts/Owned.java new file mode 100644 index 0000000..e593fdd --- /dev/null +++ b/src/java/commiteth/eth/contracts/Owned.java @@ -0,0 +1,111 @@ +package commiteth.eth.contracts; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + * Auto generated code.
+ * Do not modify!
+ * Please use the web3j command line tools, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.3.0. + */ +public final class Owned extends Contract { + private static final String BINARY = "606060405260008054600160a060020a03191633600160a060020a0316179055341561002a57600080fd5b5b6101578061003a6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313af403581146100485780638da5cb5b14610069575b600080fd5b341561005357600080fd5b610067600160a060020a0360043516610098565b005b341561007457600080fd5b61007c61011c565b604051600160a060020a03909116815260200160405180910390f35b60005433600160a060020a039081169116146100b357610118565b600054600160a060020a0380831691167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405160405180910390a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b50565b600054600160a060020a0316815600a165627a7a723058206bbc12c5f2dde30ed4acaaf0df4c0bc44e5909ce3b8ab82da7f226137465b3fd0029"; + + private Owned(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private Owned(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getNewOwnerEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("NewOwner", + Arrays.>asList(new TypeReference

() {}, new TypeReference
() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + NewOwnerEventResponse typedResponse = new NewOwnerEventResponse(); + typedResponse.old = (Address) eventValues.getIndexedValues().get(0); + typedResponse.current = (Address) eventValues.getIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable newOwnerEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("NewOwner", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public NewOwnerEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + NewOwnerEventResponse typedResponse = new NewOwnerEventResponse(); + typedResponse.old = (Address) eventValues.getIndexedValues().get(0); + typedResponse.current = (Address) eventValues.getIndexedValues().get(1); + return typedResponse; + } + }); + } + + public Future setOwner(Address _new) { + Function function = new Function("setOwner", Arrays.asList(_new), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future
owner() { + Function function = new Function("owner", + Arrays.asList(), + Arrays.>asList(new TypeReference
() {})); + return executeCallSingleValueReturnAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(Owned.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(Owned.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static Owned load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new Owned(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static Owned load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new Owned(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class NewOwnerEventResponse { + public Address old; + + public Address current; + } +} diff --git a/src/java/commiteth/eth/contracts/TokenReg.java b/src/java/commiteth/eth/contracts/TokenReg.java new file mode 100644 index 0000000..cd131e1 --- /dev/null +++ b/src/java/commiteth/eth/contracts/TokenReg.java @@ -0,0 +1,315 @@ +package commiteth.eth.contracts; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Bytes32; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + * Auto generated code.
+ * Do not modify!
+ * Please use the web3j command line tools, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.3.0. + */ +public final class TokenReg extends Contract { + private static final String BINARY = "606060405260008054600160a060020a03191633600160a060020a0316178155600455341561002d57600080fd5b5b6114ae8061003d6000396000f300606060405236156100cd5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663044215c681146100d257806313af4035146101ec57806366b42dcb1461020d57806369fe0e2d146102c05780637958533a146102d85780637b1a547c14610303578063891de9ed146103c15780638da5cb5b146104b25780639890220b146104e15780639f181b5e146104f6578063a02b161e1461051b578063b72e717d14610533578063dd93890b14610654578063ddca3f4314610672575b600080fd5b34156100dd57600080fd5b6100e8600435610697565b604051600160a060020a038087168252604082018590528216608082015260a060208201818152906060830190830187818151815260200191508051906020019080838360005b838110156101485780820151818401525b60200161012f565b50505050905090810190601f1680156101755780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156101ac5780820151818401525b602001610193565b50505050905090810190601f1680156101d95780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34156101f757600080fd5b61020b600160a060020a0360043516610846565b005b6102ac60048035600160a060020a03169060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506108bd95505050505050565b604051901515815260200160405180910390f35b34156102cb57600080fd5b61020b6004356108d7565b005b34156102e357600080fd5b6102f16004356024356108fc565b60405190815260200160405180910390f35b6102ac60048035600160a060020a03169060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052818152929190602084018383808284375094965050509235600160a060020a0316925061093b915050565b604051901515815260200160405180910390f35b34156103cc57600080fd5b61041260046024813581810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610c7895505050505050565b604051858152600160a060020a038086166020830152604082018590528216608082015260a06060820181815290820184818151815260200191508051906020019080838360005b838110156104735780820151818401525b60200161045a565b50505050905090810190601f1680156104a05780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b34156104bd57600080fd5b6104c5610dea565b604051600160a060020a03909116815260200160405180910390f35b34156104ec57600080fd5b61020b610df9565b005b341561050157600080fd5b6102f1610e55565b60405190815260200160405180910390f35b341561052657600080fd5b61020b600435610e5c565b005b341561053e57600080fd5b610552600160a060020a0360043516611075565b60405185815260408101849052600160a060020a038216608082015260a060208201818152906060830190830187818151815260200191508051906020019080838360005b838110156101485780820151818401525b60200161012f565b50505050905090810190601f1680156101755780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156101ac5780820151818401525b602001610193565b50505050905090810190601f1680156101d95780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b341561065f57600080fd5b61020b60043560243560443561122f565b005b341561067d57600080fd5b6102f16112eb565b60405190815260200160405180910390f35b60006106a16112f1565b60006106ab6112f1565b6000806003878154811015156106bd57fe5b906000526020600020906006020160005b50805460018083018054600160a060020a0390931699509293506002600019918316156101000291909101909116046020601f8201819004810201604051908101604052809291908181526020018280546001816001161561010002031660029004801561077d5780601f106107525761010080835404028352916020019161077d565b820191906000526020600020905b81548152906001019060200180831161076057829003601f168201915b5050505050945080600201549350806003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108235780601f106107f857610100808354040283529160200191610823565b820191906000526020600020905b81548152906001019060200180831161080657829003601f168201915b50505050600483015491945050600160a060020a031691505b5091939590929450565b60005433600160a060020a03908116911614610861576108b9565b600054600160a060020a0380831691167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405160405180910390a360008054600160a060020a031916600160a060020a0383161790555b5b50565b60006108cc858585853361093b565b90505b949350505050565b60005433600160a060020a039081169116146108f2576108b9565b60048190555b5b50565b600060038381548110151561090d57fe5b906000526020600020906006020160005b506000838152600591909101602052604090205490505b92915050565b600060045434101561094c57610c6f565b600160a060020a03861660009081526001602052604090205486901561097157610c6d565b85805160031461098057610c6b565b866002816040518082805190602001908083835b602083106109b457805182525b601f199092019160209182019101610994565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405190819003902054156109f357610c68565b6003805460018101610a058382611303565b916000526020600020906006020160005b60a06040519081016040908152600160a060020a03808f168352602083018e90529082018c9052606082018b90528916608082015291905081518154600160a060020a031916600160a060020a0391909116178155602082015181600101908051610a85929160200190611335565b5060408201518160020155606082015181600301908051610aaa929160200190611335565b5060808201516004919091018054600160a060020a031916600160a060020a03928316179055600354908c1660009081526001602052604090819020829055909250600291508a90518082805190602001908083835b60208310610b2057805182525b601f199092019160209182019101610b00565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390205560035460001901886040518082805190602001908083835b60208310610b8d57805182525b601f199092019160209182019101610b6d565b6001836020036101000a038019825116818451161790925250505091909101925060409150505180910390207f25074d730da65a10e171fe5589d2182313ef00da38d23a9ae3b78923568bdf2d8b89604051600160a060020a038316815260406020820181815290820183818151815260200191508051906020019080838360005b83811015610c285780820151818401525b602001610c0f565b50505050905090810190601f168015610c555780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3600193505b5b505b505b505b95945050505050565b6000806000610c856112f1565b60008060016002886040518082805190602001908083835b60208310610cbd57805182525b601f199092019160209182019101610c9d565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902054039550600386815481101515610d0357fe5b906000526020600020906006020160005b508054600280830154600384018054600160a060020a03909416995090975092935060001960018316156101000201909116046020601f820181900481020160405190810160405280929190818152602001828054600181600116156101000203166002900480156108235780601f106107f857610100808354040283529160200191610823565b820191906000526020600020905b81548152906001019060200180831161080657829003601f168201915b50505050600483015491945050600160a060020a031691505b5091939590929450565b600054600160a060020a031681565b60005433600160a060020a03908116911614610e1457610e51565b33600160a060020a03166108fc30600160a060020a0316319081150290604051600060405180830381858888f193505050501515610e5157600080fd5b5b5b565b6003545b90565b60005433600160a060020a03908116911614610e77576108b9565b80600382815481101515610e8757fe5b906000526020600020906006020160005b506001016040518082805460018160011615610100020316600290048015610ef75780601f10610ed5576101008083540402835291820191610ef7565b820191906000526020600020905b815481529060010190602001808311610ee3575b505091505060405180910390207f96e76fa77fea85d8abeb7533fdb8288c214bb1dcf1f867c8f36a95f1f509c17560405160405180910390a360016000600383815481101515610f4357fe5b906000526020600020906006020160005b5054600160a060020a031681526020810191909152604001600090812055600380546002919083908110610f8457fe5b906000526020600020906006020160005b506001016040518082805460018160011615610100020316600290048015610ff45780601f10610fd2576101008083540402835291820191610ff4565b820191906000526020600020905b815481529060010190602001808311610fe0575b5050928352505060200160405180910390206000905560038181548110151561101957fe5b906000526020600020906006020160005b8154600160a060020a03191682556110466001830160006113b4565b600282016000905560038201600061105e91906113b4565b506004018054600160a060020a03191690555b5b50565b600061107f6112f1565b60006110896112f1565b600160a060020a0385166000908152600160205260408120546003805460001990920196508291879081106110ba57fe5b906000526020600020906006020160005b509050806001018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561077d5780601f106107525761010080835404028352916020019161077d565b820191906000526020600020905b81548152906001019060200180831161076057829003601f168201915b5050505050945080600201549350806003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108235780601f106107f857610100808354040283529160200191610823565b820191906000526020600020905b81548152906001019060200180831161080657829003601f168201915b50505050600483015491945050600160a060020a031691505b5091939590929450565b8233600160a060020a031660038281548110151561124957fe5b906000526020600020906006020160005b5060040154600160a060020a031614611272576112e4565b8160038581548110151561128257fe5b906000526020600020906006020160005b50600085815260059190910160205260409081902091909155839085907f7991c63a749706fd298fc2387764d640be6e714307b6357b1d3c2ce35cba3b529085905190815260200160405180910390a35b5b50505050565b60045481565b60206040519081016040526000815290565b81548183558181151161132f5760060281600602836000526020600020918201910161132f91906113fc565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061137657805160ff19168380011785556113a3565b828001600101855582156113a3579182015b828111156113a3578251825591602001919060010190611388565b5b506113b0929150611461565b5090565b50805460018160011615610100020316600290046000825580601f106113da57506108b9565b601f0160209004906000526020600020908101906108b99190611461565b5b50565b610e5991905b808211156113b0578054600160a060020a0319168155600061142760018301826113b4565b600282016000905560038201600061143f91906113b4565b50600481018054600160a060020a0319169055600601611402565b5090565b90565b610e5991905b808211156113b05760008155600101611467565b5090565b905600a165627a7a72305820dc82243a03a763551f18919f3f3b18deb414598a49e3885231566104cf03730d0029"; + + private TokenReg(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private TokenReg(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getRegisteredEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Registered", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList(new TypeReference

() {}, new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + RegisteredEventResponse typedResponse = new RegisteredEventResponse(); + typedResponse.tla = (Utf8String) eventValues.getIndexedValues().get(0); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(1); + typedResponse.addr = (Address) eventValues.getNonIndexedValues().get(0); + typedResponse.name = (Utf8String) eventValues.getNonIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable registeredEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Registered", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList(new TypeReference
() {}, new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public RegisteredEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + RegisteredEventResponse typedResponse = new RegisteredEventResponse(); + typedResponse.tla = (Utf8String) eventValues.getIndexedValues().get(0); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(1); + typedResponse.addr = (Address) eventValues.getNonIndexedValues().get(0); + typedResponse.name = (Utf8String) eventValues.getNonIndexedValues().get(1); + return typedResponse; + } + }); + } + + public List getUnregisteredEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Unregistered", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + UnregisteredEventResponse typedResponse = new UnregisteredEventResponse(); + typedResponse.tla = (Utf8String) eventValues.getIndexedValues().get(0); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable unregisteredEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("Unregistered", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public UnregisteredEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + UnregisteredEventResponse typedResponse = new UnregisteredEventResponse(); + typedResponse.tla = (Utf8String) eventValues.getIndexedValues().get(0); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(1); + return typedResponse; + } + }); + } + + public List getMetaChangedEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("MetaChanged", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList(new TypeReference() {})); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + MetaChangedEventResponse typedResponse = new MetaChangedEventResponse(); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(0); + typedResponse.key = (Bytes32) eventValues.getIndexedValues().get(1); + typedResponse.value = (Bytes32) eventValues.getNonIndexedValues().get(0); + responses.add(typedResponse); + } + return responses; + } + + public Observable metaChangedEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("MetaChanged", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}), + Arrays.>asList(new TypeReference() {})); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public MetaChangedEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + MetaChangedEventResponse typedResponse = new MetaChangedEventResponse(); + typedResponse.id = (Uint256) eventValues.getIndexedValues().get(0); + typedResponse.key = (Bytes32) eventValues.getIndexedValues().get(1); + typedResponse.value = (Bytes32) eventValues.getNonIndexedValues().get(0); + return typedResponse; + } + }); + } + + public List getNewOwnerEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("NewOwner", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList()); + List valueList = extractEventParameters(event, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (EventValues eventValues : valueList) { + NewOwnerEventResponse typedResponse = new NewOwnerEventResponse(); + typedResponse.old = (Address) eventValues.getIndexedValues().get(0); + typedResponse.current = (Address) eventValues.getIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable newOwnerEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + final Event event = new Event("NewOwner", + Arrays.>asList(new TypeReference
() {}, new TypeReference
() {}), + Arrays.>asList()); + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public NewOwnerEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + NewOwnerEventResponse typedResponse = new NewOwnerEventResponse(); + typedResponse.old = (Address) eventValues.getIndexedValues().get(0); + typedResponse.current = (Address) eventValues.getIndexedValues().get(1); + return typedResponse; + } + }); + } + + public Future> token(Uint256 _id) { + Function function = new Function("token", + Arrays.asList(_id), + Arrays.>asList(new TypeReference
() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference
() {})); + return executeCallMultipleValueReturnAsync(function); + } + + public Future setOwner(Address _new) { + Function function = new Function("setOwner", Arrays.asList(_new), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future register(Address _addr, Utf8String _tla, Uint256 _base, Utf8String _name, BigInteger weiValue) { + Function function = new Function("register", Arrays.asList(_addr, _tla, _base, _name), Collections.>emptyList()); + return executeTransactionAsync(function, weiValue); + } + + public Future setFee(Uint256 _fee) { + Function function = new Function("setFee", Arrays.asList(_fee), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future meta(Uint256 _id, Bytes32 _key) { + Function function = new Function("meta", + Arrays.asList(_id, _key), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future registerAs(Address _addr, Utf8String _tla, Uint256 _base, Utf8String _name, Address _owner, BigInteger weiValue) { + Function function = new Function("registerAs", Arrays.asList(_addr, _tla, _base, _name, _owner), Collections.>emptyList()); + return executeTransactionAsync(function, weiValue); + } + + public Future> fromTLA(Utf8String _tla) { + Function function = new Function("fromTLA", + Arrays.asList(_tla), + Arrays.>asList(new TypeReference() {}, new TypeReference
() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference
() {})); + return executeCallMultipleValueReturnAsync(function); + } + + public Future
owner() { + Function function = new Function("owner", + Arrays.asList(), + Arrays.>asList(new TypeReference
() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future drain() { + Function function = new Function("drain", Arrays.asList(), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future tokenCount() { + Function function = new Function("tokenCount", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future unregister(Uint256 _id) { + Function function = new Function("unregister", Arrays.asList(_id), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future> fromAddress(Address _addr) { + Function function = new Function("fromAddress", + Arrays.asList(_addr), + Arrays.>asList(new TypeReference() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference() {}, new TypeReference
() {})); + return executeCallMultipleValueReturnAsync(function); + } + + public Future setMeta(Uint256 _id, Bytes32 _key, Bytes32 _value) { + Function function = new Function("setMeta", Arrays.asList(_id, _key, _value), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future fee() { + Function function = new Function("fee", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(TokenReg.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) { + return deployAsync(TokenReg.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue); + } + + public static TokenReg load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new TokenReg(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static TokenReg load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new TokenReg(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class RegisteredEventResponse { + public Utf8String tla; + + public Uint256 id; + + public Address addr; + + public Utf8String name; + } + + public static class UnregisteredEventResponse { + public Utf8String tla; + + public Uint256 id; + } + + public static class MetaChangedEventResponse { + public Uint256 id; + + public Bytes32 key; + + public Bytes32 value; + } + + public static class NewOwnerEventResponse { + public Address old; + + public Address current; + } +} From 1b9036371a22513755f68ec40823e543cee99029 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 12 Mar 2018 23:51:41 +0700 Subject: [PATCH 20/32] dont build contracts as part of uberjar task --- project.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project.clj b/project.clj index a89ee2b..d531a19 100644 --- a/project.clj +++ b/project.clj @@ -75,10 +75,10 @@ :less {:source-paths ["src/less"] :target-path "resources/public/css"} - :auto {"build-contracts" {:file-pattern #"\.(sol)\n" - :paths ["./contracts"]}} + ;; :auto {"build-contracts" {:file-pattern #"\.(sol)\n" + ;; :paths ["./contracts"]}} - :aliases {"build-contracts" ["shell" "./build_contracts.sh"]} + ;; :aliases {"build-contracts" ["shell" "./build_contracts.sh"]} :ring {:destroy commiteth.scheduler/stop-scheduler} @@ -94,7 +94,7 @@ :profiles {:uberjar {:jvm-opts ["-server" "-Dconf=config-prod.edn"] :omit-source true - :prep-tasks ["build-contracts" "javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]] + :prep-tasks [#_"build-contracts" "javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]] :cljsbuild {:builds {:min From 006d6d6bdf7dd371ac4b35a73379dff8428ea17a Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 13:58:53 +0100 Subject: [PATCH 21/32] update contract building docs + add decision record --- README.md | 25 +++-------- contracts/README.md | 31 ++++++++++++++ build_contracts.sh => contracts/build.sh | 0 ...include-compiled-web3j-contracts-in-git.md | 42 +++++++++++++++++++ project.clj | 9 +--- 5 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 contracts/README.md rename build_contracts.sh => contracts/build.sh (100%) create mode 100644 doc/decisions/0003-include-compiled-web3j-contracts-in-git.md diff --git a/README.md b/README.md index ced4f88..8266b37 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ The `develop` branch is automatically deployed here. - [Prerequisites](#prerequisites) - [Application config](#application-config) - [GitHub integration](#github-integration) +- [Contracts](#contracts) - [Running](#running) - [Testing](#testing) - [More info](#more-info) @@ -37,26 +38,6 @@ psql postgres -c "CREATE USER commiteth WITH PASSWORD 'commiteth';" psql postgres -c "CREATE DATABASE commiteth;" ``` -### solc - -Solidity compiler [0.4.15](https://github.com/ethereum/solidity/releases/tag/v0.4.15) is required and needs to be in $PATH. -Detailed [installation instructions for various platforms](https://solidity.readthedocs.io/en/develop/installing-solidity.html) can be found in the official Solidity documentation. - -``` -brew install https://raw.githubusercontent.com/ethereum/homebrew-ethereum/de1da16f7972a899fc8dd1f3f04299eced6f4312/solidity.rb -brew pin solidity -``` - -### web3j - -Web3j [2.3.0](https://github.com/web3j/web3j/releases/tag/v2.3.0) is required and the command line tools need to be in $PATH. -Installation instructions for the command line tools can be found in the [Web3j Command Line Tools documentation](https://docs.web3j.io/command_line.html). - -``` -brew install https://raw.githubusercontent.com/web3j/homebrew-web3j/881cf369b551a5f2557bd8fb02fa8b7b970256ca/web3j.rb -brew pin web3j -``` - ## Application config Make sure to create `/config-dev.edn` and populate it correctly, which is based on `env/dev/resources/config.edn`. Description of config fields is given below: @@ -91,6 +72,10 @@ Follow the steps [here](https://developer.github.com/apps/building-oauth-apps/cr ### GitHub App Follow the steps [here](https://developer.github.com/apps/building-github-apps/creating-a-github-app/). Be sure to specify `:server-address` + `/webhook-app` as "Webhook URL", and `:webhook-secret` as "Webhook Secret". +## Contracts + +All information related to development of OpenBounty smart contracts can be found in [`contracts/`](/contracts/) + ## Running ### Ethereum node diff --git a/contracts/README.md b/contracts/README.md new file mode 100644 index 0000000..f92dc0e --- /dev/null +++ b/contracts/README.md @@ -0,0 +1,31 @@ +# OpenBounty Contracts + +This directory contains all the underlying smart contracts used by the OpenBounty platform. + +- A script `contracts/build.sh` is part of this repository and can be used to +compile the contracts and copy Java interfaces into `src/java/`. + +In order to run the script the following dependencies have to be met: + +- [solc](#solc) +- [web3j](#web3j) + +### solc + +Solidity compiler [0.4.15](https://github.com/ethereum/solidity/releases/tag/v0.4.15) is required and needs to be in $PATH. +Detailed [installation instructions for various platforms](https://solidity.readthedocs.io/en/develop/installing-solidity.html) can be found in the official Solidity documentation. + +``` +brew install https://raw.githubusercontent.com/ethereum/homebrew-ethereum/de1da16f7972a899fc8dd1f3f04299eced6f4312/solidity.rb +brew pin solidity +``` + +### web3j + +Web3j [2.3.0](https://github.com/web3j/web3j/releases/tag/v2.3.0) is required and the command line tools need to be in $PATH. +Installation instructions for the command line tools can be found in the [Web3j Command Line Tools documentation](https://docs.web3j.io/command_line.html). + +``` +brew install https://raw.githubusercontent.com/web3j/homebrew-web3j/881cf369b551a5f2557bd8fb02fa8b7b970256ca/web3j.rb +brew pin web3j +``` \ No newline at end of file diff --git a/build_contracts.sh b/contracts/build.sh similarity index 100% rename from build_contracts.sh rename to contracts/build.sh diff --git a/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md b/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md new file mode 100644 index 0000000..44ca86e --- /dev/null +++ b/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md @@ -0,0 +1,42 @@ +# 0003. Include Compiled Web3j Contracts in Git + +| Date | Tags | +|---|---| +| 2018-03-20 | contracts, tooling | + + +## Status + +Accepted + +## Context + +The OpenBounty project utilizes smart contracts to make certain core +aspects of it's product work without centralized trust. + +In order to develop the platform a Java interface to these contracts needs to +be built beforehand. To create those interfaces various tools are required +(`web3j` & `solc`), often in specific versions that are not easily available +via widespread package managers. + +This hurdle also applies to any other situations where the application is set +up from scratch, e.g. continuous integration. + +## Decision + +Instead of forcing every contributor to install those tools we will include +the compiled Java interfaces in our Git repository. This removes a significant +setup cost and hopefully allows people to get going much faster. + +Installing `web3j` and `solc` will only be required when hacking on the +contracts itself which are much more stable than the majority of the code. + +An alternative would be implementing scripts that install those tools in a +platform independent manner but this would require more work. Once we have +the time or someone wants to work on creating those scripts we can easily +revert the decision outlined in this document. + +## Consequences + +- The compiled Java interfaces may get out of date. + This could perhaps be addressed by some clever use of checksums. diff --git a/project.clj b/project.clj index d531a19..c4b6de5 100644 --- a/project.clj +++ b/project.clj @@ -66,20 +66,13 @@ :plugins [[lein-cprop "1.0.1"] [migratus-lein "0.4.1"] [lein-cljsbuild "1.1.7"] - [lein-auto "0.1.2"] [lein-less "1.7.5"] - [lein-shell "0.5.0"] [lein-sha-version "0.1.1"]] :less {:source-paths ["src/less"] :target-path "resources/public/css"} - ;; :auto {"build-contracts" {:file-pattern #"\.(sol)\n" - ;; :paths ["./contracts"]}} - - ;; :aliases {"build-contracts" ["shell" "./build_contracts.sh"]} - :ring {:destroy commiteth.scheduler/stop-scheduler} :uberjar-exclusions [#"public/README.md" #"public/cards.html"] @@ -94,7 +87,7 @@ :profiles {:uberjar {:jvm-opts ["-server" "-Dconf=config-prod.edn"] :omit-source true - :prep-tasks [#_"build-contracts" "javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]] + :prep-tasks ["javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]] :cljsbuild {:builds {:min From ef5dcaf66b4ff46a05370868e6d70518cda1771b Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 14:06:25 +0100 Subject: [PATCH 22/32] dont clean java source paths --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index c4b6de5..16209a7 100644 --- a/project.clj +++ b/project.clj @@ -77,7 +77,7 @@ :uberjar-exclusions [#"public/README.md" #"public/cards.html"] :clean-targets ^{:protect false} - [:target-path :java-source-paths [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]] + [:target-path [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]] :figwheel {:http-server-root "public" :nrepl-port 7002 From 400f848e08dcd98969ad9ca89c2624f9d109753f Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 14:18:15 +0100 Subject: [PATCH 23/32] note about visibility of contract API changes --- doc/decisions/0003-include-compiled-web3j-contracts-in-git.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md b/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md index 44ca86e..89c5bfb 100644 --- a/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md +++ b/doc/decisions/0003-include-compiled-web3j-contracts-in-git.md @@ -40,3 +40,5 @@ revert the decision outlined in this document. - The compiled Java interfaces may get out of date. This could perhaps be addressed by some clever use of checksums. +- By having changes to the contract interfaces be part of a changeset it may + be easier to spot what changes are required/how APIs are changing. From df93a502df957d418f95873a19ebccf685fe1a28 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Mon, 26 Mar 2018 14:08:31 +0300 Subject: [PATCH 24/32] Parse issue URLs during issue number extraction --- src/clj/commiteth/routes/webhooks.clj | 41 +++++++++++++++------------ test/clj/commiteth/test/github.clj | 12 ++++++-- test/clj/commiteth/test/webhooks.clj | 6 ++-- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index e12ccd6..e8f2f03 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -82,28 +82,33 @@ (when (issues/is-bounty-issue? issue-id) (issues/update-open-status issue-id true))) -(def ^:const keywords - [#"(?i)close:?\s+#(\d+)" - #"(?i)closes:?\s+#(\d+)" - #"(?i)closed:?\s+#(\d+)" - #"(?i)fix:?\s+#(\d+)" - #"(?i)fixes:?\s+#(\d+)" - #"(?i)fixed:?\s+#(\d+)" - #"(?i)resolve:?\s?#(\d+)" - #"(?i)resolves:?\s+#(\d+)" - #"(?i)resolved:?\s+#(\d+)"]) +(defn pr-keywords [prefix] + (mapv + #(re-pattern (str "(?i)" %1 ":?\\s+" prefix "(\\d+)")) + ["close" + "closes" + "closed" + "fix" + "fixes" + "fixed" + "resolve" + "resolves" + "resolved"])) (defn extract-issue-number - [pr-body pr-title] + [owner repo pr-body pr-title] (let [cleaned-body (str/replace pr-body #"(?m)^\[comment.*$" "") + keywords (concat (pr-keywords "#") + (when-not (or (str/blank? owner) (str/blank? repo)) + (pr-keywords (str "https://github.com/" owner "/" repo "/")))) extract (fn [source] (mapcat #(keep - (fn [s] - (try (let [issue-number (Integer/parseInt (second s))] - (when (pos? issue-number) - issue-number)) - (catch NumberFormatException _))) - (re-seq % source)) keywords))] + (fn [s] + (try (let [issue-number (Integer/parseInt (second s))] + (when (pos? issue-number) + issue-number)) + (catch NumberFormatException _))) + (re-seq % source)) keywords))] (log/debug cleaned-body) (concat (extract cleaned-body) (extract pr-title)))) @@ -169,7 +174,7 @@ pr-body :body pr-title :title} :pull_request}] (log/info "handle-pull-request-event" event-type owner repo repo-id login pr-body pr-title) - (if-let [issue (some->> (extract-issue-number pr-body pr-title) + (if-let [issue (some->> (extract-issue-number owner repo pr-body pr-title) (first) (issues/get-issue repo-id))] (if-not (:commit_sha issue) ; no PR has been merged yet referencing this issue diff --git a/test/clj/commiteth/test/github.clj b/test/clj/commiteth/test/github.clj index 96e2416..6161dde 100644 --- a/test/clj/commiteth/test/github.clj +++ b/test/clj/commiteth/test/github.clj @@ -4,14 +4,20 @@ (deftest test-github-keywords (testing "Several keywords in mixed case" - (let [res (set (extract-issue-number "body" + (let [res (set (extract-issue-number "" "" "body" "Fixes #12 and cloSes #000028 and also resolved \n#32"))] (is (= #{12 28 32} res)))) (testing "Ignoring big numbers and zeroes" - (let [res (set (extract-issue-number "body" + (let [res (set (extract-issue-number "" "" "body" "Fixes #298374298229087345 and closes #0xFFEF"))] (is (= #{} res)))) (testing "Consider both body and title" - (let [res (set (extract-issue-number "Fixes #1" + (let [res (set (extract-issue-number "" "" + "Fixes #1" "Fixes #2"))] + (is (= #{1 2} res)))) + (testing "Use issue URL instead of number" + (let [res (set (extract-issue-number "status-im" "status-react" + "Fixes https://github.com/status-im/status-react/1" + "Fixes https://github.com/status-im/status-react/2"))] (is (= #{1 2} res))))) diff --git a/test/clj/commiteth/test/webhooks.clj b/test/clj/commiteth/test/webhooks.clj index 5395877..dfb0a56 100644 --- a/test/clj/commiteth/test/webhooks.clj +++ b/test/clj/commiteth/test/webhooks.clj @@ -7,15 +7,15 @@ (testing "Basic fixes case from PR body" (let [title "foo" body "fixes #123"] - (is (= '(123) (webhooks/extract-issue-number body title))))) + (is (= '(123) (webhooks/extract-issue-number "" "" body title))))) (testing "Basic fixes case from PR title" (let [title "My title (fixes: #123)" body "no use for a body"] - (is (= '(123) (webhooks/extract-issue-number body title))))) + (is (= '(123) (webhooks/extract-issue-number "" "" body title))))) (testing "Commented issue number ignored in PR body" (let [title "foo" body " fixes #123 [comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566) "] - (is (= '(123) (webhooks/extract-issue-number body title)))))) + (is (= '(123) (webhooks/extract-issue-number "" "" body title)))))) From 3c6dee0f14fa0b2256902dace81583d44f382a49 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Mon, 26 Mar 2018 22:57:39 +0300 Subject: [PATCH 25/32] Add issues to issue links in PRs --- src/clj/commiteth/routes/webhooks.clj | 2 +- test/clj/commiteth/test/github.clj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index e8f2f03..3a7e44f 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -100,7 +100,7 @@ (let [cleaned-body (str/replace pr-body #"(?m)^\[comment.*$" "") keywords (concat (pr-keywords "#") (when-not (or (str/blank? owner) (str/blank? repo)) - (pr-keywords (str "https://github.com/" owner "/" repo "/")))) + (pr-keywords (str "https://github.com/" owner "/" repo "/issues/")))) extract (fn [source] (mapcat #(keep (fn [s] diff --git a/test/clj/commiteth/test/github.clj b/test/clj/commiteth/test/github.clj index 6161dde..edcad3b 100644 --- a/test/clj/commiteth/test/github.clj +++ b/test/clj/commiteth/test/github.clj @@ -18,6 +18,6 @@ (is (= #{1 2} res)))) (testing "Use issue URL instead of number" (let [res (set (extract-issue-number "status-im" "status-react" - "Fixes https://github.com/status-im/status-react/1" - "Fixes https://github.com/status-im/status-react/2"))] + "Fixes https://github.com/status-im/status-react/issues/1" + "Fixes https://github.com/status-im/status-react/issues/2"))] (is (= #{1 2} res))))) From 770d06df31622c1c2f7a59f548d74749371dc3ad Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 12 Mar 2018 23:32:28 +0700 Subject: [PATCH 26/32] add experimental circleci config --- .circleci/config.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..024d735 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,43 @@ +# Clojure CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-clojure/ for more details +# +version: 2 +jobs: + build: + docker: + # specify the version you desire here + - image: circleci/clojure:lein-2.7.1 + + # Specify service dependencies here if necessary + # CircleCI maintains a library of pre-built images + # documented at https://circleci.com/docs/2.0/circleci-images/ + # - image: circleci/postgres:9.4 + + working_directory: ~/repo + + environment: + LEIN_ROOT: "true" + # Customize the JVM maximum heap limit + JVM_OPTS: -Xmx3200m + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v1-dependencies-{{ checksum "project.clj" }} + # fallback to using the latest cache if no exact match is found + - v1-dependencies- + + - run: lein deps + + - save_cache: + paths: + - ~/.m2 + key: v1-dependencies-{{ checksum "project.clj" }} + + # run tests! + - run: lein test + - run: lein with-profile test doo phantom test From 1669ebcb8182e1c96118fc1a2a64a2d9d6d5b55e Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 13 Mar 2018 00:01:16 +0700 Subject: [PATCH 27/32] configure circleci postgres container --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 024d735..f69ddc3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,10 @@ jobs: # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ # - image: circleci/postgres:9.4 + - image: circleci/postgres:9.6 + environment: + - POSTGRES_USER=commiteth + - POSTGRES_DB=commiteth working_directory: ~/repo From 0ad1b16e47d12128978d2a4fbaaeababd64a96e6 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 11:31:10 +0100 Subject: [PATCH 28/32] create wallet for testing --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f69ddc3..7f95d8f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,8 @@ jobs: - ~/.m2 key: v1-dependencies-{{ checksum "project.clj" }} + - run: echo $ETH_WALLET_JSON > $ETH_WALLET_FILE + # run tests! - run: lein test - run: lein with-profile test doo phantom test From 962d29d0a7a7c787754c910bbfa1b5f520f8e1c4 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 20 Mar 2018 12:56:15 +0100 Subject: [PATCH 29/32] use browser image which includes phantomjs --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7f95d8f..a036da8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: build: docker: # specify the version you desire here - - image: circleci/clojure:lein-2.7.1 + - image: circleci/clojure:lein-2.8.1-browsers # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images From 309a2f31a36fb719d5bd79bf0f76246862406bfa Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 21 Mar 2018 18:16:50 +0100 Subject: [PATCH 30/32] disable cljs tests as there are none --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a036da8..d4726f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -46,4 +46,3 @@ jobs: # run tests! - run: lein test - - run: lein with-profile test doo phantom test From d3afe111a2fffeec12398e1a5d264aa8b4890481 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 26 Mar 2018 18:26:48 +0200 Subject: [PATCH 31/32] document circleCI stuff in README --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8266b37..66ddc01 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,21 @@ lein with-profile test figwheel devcards Open http://localhost:3449/cards.html -### Update landing page +### CircleCI + +We use CircleCI to run unit tests. The following env vars need to be set for this to work: + +> These env vars override configuration parameters that are usually set using the `config.edn` file. + +- `ETH_ACCOUNT` - as in `config.edn` +- `ETH_PASSWORD` - as in `config.edn` +- `ETH_RPC_URL` - as in `config.edn` +- `ETH_WALLET_FILE` - as in `config.edn` +- `ETH_WALLET_JSON` - contents of this will be written to `ETH_WALLET_FILE` + +:bulb: Ideally we'd create those parameters in a script. PR welcome. + +## Update landing page Landing page is static and different CSS and JS due to time constraints. From dd700ab3d39c14ccd0e25fb50e6fb23efacd8e2c Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 22 Feb 2018 10:03:31 +0100 Subject: [PATCH 32/32] improve exception when contract cannot be loaded --- src/clj/commiteth/eth/token_registry.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clj/commiteth/eth/token_registry.clj b/src/clj/commiteth/eth/token_registry.clj index 9135f8d..4d1ddea 100644 --- a/src/clj/commiteth/eth/token_registry.clj +++ b/src/clj/commiteth/eth/token_registry.clj @@ -37,6 +37,7 @@ ([addr] (println "addr" addr) (let [contract (load-tokenreg-contract addr)] + (assert contract (format "Could not load contract for addr %s" addr)) ;(assert (.isValid contract)) ;; web3j's isValid can't be trusted... (let [token-count (-> contract .tokenCount .get .getValue)] (log/debug "token-count" token-count)