Compare commits

...

129 Commits

Author SHA1 Message Date
jebba a8595591f0 README 2021-04-05 15:16:32 -06:00
jebba cd8161a10d dark theme, minimal 2021-04-05 15:05:12 -06:00
jebba f4f7612655 more minimal 2021-04-05 14:25:58 -06:00
jebba e2a3404b06 dont pull css from cdn 2021-04-05 14:21:23 -06:00
jebba afabba64a9 minimal interface 2021-04-05 14:17:49 -06:00
jebba 473df3d139 listen on localhost, use remote host for eth 2021-04-05 13:38:29 -06:00
jebba a337163a2d deepcrayon maintainer 2021-04-05 13:31:25 -06:00
jebba 65be7edda2 just build ethereum blockbook, not backend 2021-04-05 13:31:16 -06:00
jebba 0c93f8803d no public_test.go ... 2021-04-05 13:29:13 -06:00
jebba 8fd633c6d3 dont use ssl 2021-04-05 13:08:44 -06:00
jebba 2771784113 systemd, dont want backend 2021-04-05 13:07:38 -06:00
jebba f05eff6b13 dont require backend dep 2021-04-05 13:05:55 -06:00
jebba 7ba8d7f143 s/github/spacecruft 2021-04-05 12:59:11 -06:00
jebba 14c92e8bd5 make 2021-04-05 12:59:00 -06:00
jebba 4b352b5bbc template go use spacecruft 2021-04-05 12:50:52 -06:00
jebba 124717da69 spacecruft go, not github 2021-04-05 12:19:28 -06:00
jebba 2f1c4bc3af use spacecruft repo 2021-04-05 11:55:41 -06:00
jebba 0ce520d1d5 unbrand a bit 2021-04-05 11:41:26 -06:00
jebba 8ef0a2a3d5 star favicon 2021-04-05 11:37:51 -06:00
jebba 27c9434383 about/tos 2021-04-05 11:37:06 -06:00
jebba fb64efefdc fork 2021-04-05 11:34:28 -06:00
kaladin 1f6cddd4ab
Websocket new transaction (#574) 2021-03-21 21:55:25 +01:00
CodeFace 78c8a9d499 bump Qtum 0.20.2 2021-03-21 18:23:31 +01:00
Vitalij DovhanyÄŤ d8640f4e2f
zec (+testnet): 4.2.0 → 4.3.0 (#580)
Co-authored-by: 1000101 <b1000101@pm.me>
2021-03-11 16:45:28 +01:00
vdovhanyc d588904fb3 dogecoin: 1.14.2 → 1.14.3 2021-03-11 13:37:22 +01:00
Martin Boehm e6e6e64351 Adjust ethereum backend CLI flags for geth version 1.10 2021-03-09 14:03:49 +01:00
jsimon 61c2834002 eth (+testnet): 1.9.24 → 1.10.1 2021-03-09 12:52:58 +01:00
Martin Boehm 0ae8ba57a2 Update for geth version 1.10
- remove workaround for to low maxRequestContentLength
- stop using obsolete eth_protocolVersion RPC call
2021-03-09 11:37:35 +01:00
Martin Boehm 8f3106d009 Return filtered token balance in case of an empty account #566 2021-03-04 16:17:47 +01:00
vdovhanych 099a158f8c etc: 1.11.20 → 1.11.22 2021-02-24 13:29:30 +01:00
Perlover 37c7f4fbd1 Ubuntu 20.04 doesn't work without this patch
The problem was described here:

https://github.com/trezor/blockbook/issues/568
2021-02-23 21:12:08 +01:00
Martin Boehm db597c1f66 Update build documentation 2021-02-18 09:14:58 +01:00
Martin Boehm dcbcb99055 Add possibility to build from BASE_IMAGE 2021-02-18 09:14:58 +01:00
Martin Boehm 212b767925 Add TCMALLOC option to build of rocksdb 2021-02-18 09:14:58 +01:00
WO 3fe28d185c Bump Koto to 4.2.0 2021-01-27 09:41:12 +01:00
Rikard Wissing d0a1cb29f6 Update myriad backend to 0.18.1.0 2021-01-27 09:23:50 +01:00
Martin Boehm 2be5930862 Update ports registry and copyright year #549 2021-01-21 21:43:09 +01:00
Yusaku Senga 5fdc26bc14
feat: Support Ethereum Goerli testnet (#550) 2021-01-21 21:39:37 +01:00
Martin Boehm 7e54336e0c Return info about backend in websocket getInfo request 2021-01-21 10:31:04 +01:00
Martin Boehm 7dffe2e0f9 Show consensus in explorer index page 2021-01-21 10:31:04 +01:00
Martin Boehm d992369426 Fix linting issues 2021-01-21 10:29:25 +01:00
David Hill d97b5e14e8
Update Decred (#385)
Co-authored-by: Martin <martin.boehm@1mbsoftware.net>
2021-01-21 09:25:07 +01:00
JoHnY 9df39273ea vtc (+testnet): 0.15.0.1 → 0.17.1 2021-01-18 12:37:16 +01:00
Pavol Rusnak 66c072bf25 btc (+testnet): 0.20.1 -> 0.21.0 2021-01-16 21:56:16 +01:00
Jin Eguchi 505d859f91
bitcoin_signet: 0.21.0rc2 -> 0.21.0 (#554) 2021-01-16 21:46:23 +01:00
Dehumanizer77 d631bf9265 bch (+testnet): 22.1.0 → 22.2.0 2021-01-07 19:22:59 +01:00
Martin Kuvandzhiev 295b630ec8
Adding Bitcoin Gold Testnet to the configurations (#532)
Co-authored-by: Martin <martin.boehm@1mbsoftware.net>
2020-12-29 23:19:53 +01:00
Dehumanizer77 b4149946bd zec (+testnet): 4.1.1 → 4.2.0 2020-12-29 21:21:48 +01:00
Dehumanizer77 6981222a43 etc: 1.11.18 → 1.11.20 2020-12-29 21:18:54 +01:00
Peter John Bushnell bb9fce02cb
Add Trezarcoin (TZC) (#423)
Co-authored-by: Martin <martin.boehm@1mbsoftware.net>
2020-12-29 01:39:37 +01:00
Jin Eguchi 077e637093
add bitcoin-signet (#533) 2020-12-29 00:47:50 +01:00
araarakelyan1985 15b88ef23d
Rebranding from Zcoin to Firo (#538) 2020-12-28 23:38:56 +01:00
Martin 4697d756e0 Fix display of RBF flag in tx view 2020-12-28 23:05:02 +01:00
Martin 4766110255 Add RBF info to txdetail 2020-12-28 23:05:02 +01:00
Tomas Susanka 360cac85f6 chore(static): show RBF in the transaction detail 2020-12-28 23:05:02 +01:00
jackielove4u 554041c32c Bump Groestlcoin backend version to 2.21.0 2020-12-28 22:36:30 +01:00
CodeFace d12e6551ea bump Qtum 0.20.1 2020-12-08 22:50:12 +01:00
Martin Boehm 96e8329171 Update documentation #483 2020-12-04 12:40:39 +01:00
Martin Boehm f094ee578d Merge branch 'braydonf-docs' 2020-12-04 12:09:32 +01:00
Martin Boehm 00352cb5fe Merge branch 'docs' of https://github.com/braydonf/blockbook into braydonf-docs 2020-12-04 12:08:36 +01:00
CryptoManiac c0c2dc4151 You have to link against libdl on Linux
Otherwise there will be linking error because rocksdb is importing ```dlclose```, ```dlopen``` and other functions from libdl.so.
2020-12-04 12:05:33 +01:00
Martin Boehm da1c0d762e Unify error handling of GetTransactionSpecific #395 2020-12-04 11:57:11 +01:00
Martin Boehm fc267ed2f4 Return for mempool transactions coinSpecificData #522 2020-12-04 11:57:11 +01:00
Martin Boehm 69d13e0688 Fix ETH Ropsten: websocket: read limit exceeded #490
Geth sets maxRequestContentLength to 5M.
However, Ropsten contains blocks of largers size (for example 599281).
These which cannot be fetched using API.

Fixed by hacky way of modifying the geth source before
the build of the project.
Will submit PR to go-ethereum with final fix.
2020-12-04 11:57:11 +01:00
Martin Boehm 248de3cb34 Detect fork in connectBlocks loop 2020-12-04 11:57:11 +01:00
Martin Boehm 636167c72a Store to txcache old eth transactions without status 2020-12-04 11:57:11 +01:00
Martin Boehm 24a783be50 Move websocket connection close out of channel close mutex 2020-12-04 11:57:11 +01:00
Martin Boehm 579b42cf27 Stop using mod vendor in Blockbook build 2020-12-04 11:57:11 +01:00
Martin Boehm 576b8b57b7 Upgrade to go 1.15.6, rocksdb 6.13.3 and other dependecies 2020-12-04 11:57:11 +01:00
Martin Kuvandzhiev 786047f8c2 Updating the API docs so it shows more information about the web socket communication 2020-12-04 11:53:03 +01:00
Dehumanizer77 3ccfd181b7 zcash (+testnet): 4.1.0 → 4.1.1 2020-11-23 12:00:01 +01:00
Dehumanizer77 6274f4b3d4 zcash (+testnet): 4.0.0 → 4.1.0 2020-11-16 17:06:24 +01:00
Dehumanizer77 2b786c9832 eth (+testnet): 1.9.21 → 1.9.24 2020-11-16 17:01:58 +01:00
Dehumanizer77 bc009454d0 dash (+testnet): 0.15.0.0 → 0.16.0.1 2020-11-16 16:01:37 +01:00
Dehumanizer77 5e7d0e9f75 etc: 1.11.15 → 1.11.18 2020-11-16 15:59:54 +01:00
Pavol Rusnak c915f35224
bch(+testnet): 0.22.6 -> 22.1.0 (switch to Bitcoin Cash Node)
use spoofed subversion to not confuse wallets
2020-11-16 12:26:42 +01:00
Pavol Rusnak 3369295e10
bch(+testnet): 0.22.0 -> 0.22.6 (switch to BCHN) (#511) 2020-11-16 11:43:52 +01:00
hewigovens 5534372e7c
[Zcash] Expose zcash consensus info (#508) 2020-11-12 19:56:41 +01:00
Martin Boehm fc25200ff8 Fix ineffassign errors 2020-11-12 15:41:51 +01:00
Martin Boehm 3d9954bf79 Improve locking and add panic handlers to websocket functionality 2020-11-12 15:31:59 +01:00
nezero 214d0144ef Ignore DeepOnion QT 2020-11-06 10:21:19 +01:00
Liam Alford ec79702bab Bump DeepOnion Version to v2.2 2020-11-06 10:21:19 +01:00
Scotty0448 e666e7c5a4 Bump Ritocoin backend to 2.4.2.0 2020-11-06 10:19:31 +01:00
JoHnY 4832205f45 etc: 1.11.12 -> 1.11.15 2020-10-06 14:23:07 +02:00
1000101 b05346b1a1 eth (+testnet): 1.9.20 -> 1.9.21 2020-09-15 00:51:23 +02:00
WO dcf77a5680 Bump Koto to 4.0.0 2020-09-15 00:35:17 +02:00
1000101 7f1cf09d05 zec (+testnet): 3.1.0 -> 4.0.0 2020-09-08 11:24:32 +02:00
Martin a1993173ab
Go ethereum v1.9.20 (#482) issue #481
Handle different behavior of geth from v1.9.15
Bump go-ethereum dependecy to v1.9.20
2020-09-03 10:11:37 +02:00
jackielove4u bea6b6230f Add fiat rates for Groestlcoin 2020-09-01 10:10:33 +02:00
jackielove4u 72486c606f Bump Groestlcoin backend version to 2.20.1 2020-08-26 13:28:36 +02:00
1000101 a8ee6aefb0 bch(+testnet): 0.21.10->0.22.0 2020-08-26 13:24:57 +02:00
1000101 52cbc7162d eth(+testnet): 1.9.19->1.9.20 2020-08-26 10:31:22 +02:00
Pavol Rusnak 81ce876d8b
nix: add dependencies to shell.nix 2020-08-21 16:11:21 +02:00
Braydon Fuller 7b70ee0ad0
Add blockchaincfg.json to .gitignore 2020-08-20 15:21:55 -07:00
Braydon Fuller a83cb7684f
Update build documentation 2020-08-20 15:21:23 -07:00
Pavol Rusnak 0f4eadd935
nix: add trivial shell.nix for development 2020-08-20 17:52:58 +02:00
1000101 e66fa79383 btg: 0.17.2->0.17.3 2020-08-20 10:34:33 +02:00
1000101 f99406e9cf zec(+testnet): 3.0.0->3.1.0 2020-08-20 10:34:04 +02:00
1000101 be73064223 eth(+testnet): 1.9.13->1.9.19 2020-08-20 10:24:28 +02:00
Panu 79907e7aa5
Update Zcoin transaction parser and bump binary version (#466) 2020-08-20 10:23:23 +02:00
1000101 2fb1e779c0 etc: 1.11.7->1.11.12 2020-08-20 10:15:17 +02:00
1000101 a530f5612a btc(+testnet): 0.20.0->0.20.1 2020-08-20 10:05:21 +02:00
Martin Boehm ab285c6b05 Increase max size of reorg of ETC to 10000 blocks 2020-08-06 10:27:08 +02:00
Martin Boehm 17c9080135 Include eth transactions in unknown status into balance history 2020-07-30 16:02:08 +02:00
1000101 791948623e bgold: 0.15.2->0.17.2 2020-07-16 00:46:35 +02:00
Scotty0448 af5e8f18ba Bump Ravencoin backend to 4.2.1.0 2020-07-15 23:55:12 +02:00
root 07ac3c8401 bcash (+testnet): Bump backend 0.21.0 -> 0.21.10 2020-07-07 16:56:44 +02:00
Martin Boehm 83616bce83 Fix integration tests script 2020-06-30 15:06:11 +02:00
codeface 22145d0cc2 bump Qtum 0.19.1 2020-06-29 17:35:30 +02:00
Dehumanizer77 92ae2052c3 etc: Bump backend 1.11.2->1.11.7 2020-06-29 17:17:36 +02:00
Dehumanizer77 30149e51d2 ltc (+testnet): Bump backend 0.17.1->0.18.1 2020-06-29 17:08:52 +02:00
Martin Boehm abb6453fb3 Fix dash testnet config #447 2020-06-22 18:40:54 +02:00
Martin Boehm eb4e10ac67 Bump Blockbook version to 0.3.4 2020-06-12 11:52:21 +02:00
1000101 5350027e1d btc (+testnet): Bump backend 0.19.0.1->0.20.0 2020-06-03 18:46:00 +02:00
1000101 7d6c61623e zec (+testnet): Bump backend 2.1.2->3.0.0 2020-05-29 20:03:01 +02:00
Martin Boehm 994567aed9 Add fee value to unspent transactions balance 2020-05-26 23:21:25 +02:00
Martin Boehm dd7964297d Suppress logging of MQ errors 2020-05-24 19:18:23 +02:00
Martin Boehm 3be3bb5c3d Regenerate registry of ports 2020-05-24 17:58:44 +02:00
Martin Boehm 0a3ea6e225 Send websocket notification on new tx for input addresses 2020-05-24 17:58:29 +02:00
Martin Boehm bc001ce3a3 Make logs cleaner by not logging public API errors in websocket 2020-05-22 11:19:37 +02:00
Martin Boehm 76324be8ec Modify logging 2020-05-21 22:43:18 +02:00
Martin Boehm 01d8e48e73 Unconfirmed eth balance not being updated #408 2020-05-21 18:05:16 +02:00
Martin Boehm ff607bc334 Check ERC20 contract balance if no transactions were done for address 2020-05-21 18:05:16 +02:00
Martin Boehm e60c320ae7 Allow parameters value, gasPrice and gas to be passed to ETH estimateFee 2020-05-21 18:05:16 +02:00
Martin Boehm dd2dc6b2ee Add sentToSelf to BalanceHistory 2020-05-21 18:05:16 +02:00
wakiyamap b957ed66ab Add fiat rate(monacoin) 2020-05-20 00:05:26 +02:00
Adam Collier 3ebe99edb2
Add support for DigiByte Testnet (#432) 2020-05-19 23:58:46 +02:00
v bad9f992e1 eth-like backends listen on localhost instead * 2020-05-19 23:56:35 +02:00
jackielove4u 707ac28954 Bump Groestlcoin backend version to 2.19.1 2020-05-12 21:56:47 +02:00
249 changed files with 4538 additions and 3116 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ debug*
docker/blockbook
build/pkg-defs
build/blockbook
build/blockchaincfg.json
build/ldb
build/sst_dump
build/*.deb

View File

@ -1,8 +1,9 @@
BIN_IMAGE = blockbook-build
DEB_IMAGE = blockbook-build-deb
PACKAGER = $(shell id -u):$(shell id -g)
BASE_IMAGE = $$(awk -F= '$$1=="ID" { print $$2 ;}' /etc/os-release):$$(awk -F= '$$1=="VERSION_ID" { print $$2 ;}' /etc/os-release | tr -d '"')
NO_CACHE = false
UPDATE_VENDOR = 1
TCMALLOC =
ARGS ?=
TARGETS=$(subst .json,, $(shell ls configs/coins))
@ -10,28 +11,28 @@ TARGETS=$(subst .json,, $(shell ls configs/coins))
.PHONY: build build-debug test deb
build: .bin-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(BIN_IMAGE) make build ARGS="$(ARGS)"
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(BIN_IMAGE) make build ARGS="$(ARGS)"
build-debug: .bin-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(BIN_IMAGE) make build-debug ARGS="$(ARGS)"
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(BIN_IMAGE) make build-debug ARGS="$(ARGS)"
test: .bin-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test ARGS="$(ARGS)"
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test ARGS="$(ARGS)"
test-integration: .bin-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test-integration ARGS="$(ARGS)"
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test-integration ARGS="$(ARGS)"
test-all: .bin-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test-all ARGS="$(ARGS)"
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" --network="host" $(BIN_IMAGE) make test-all ARGS="$(ARGS)"
deb-backend-%: .deb-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh backend $* $(ARGS)
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh backend $* $(ARGS)
deb-blockbook-%: .deb-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh blockbook $* $(ARGS)
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh blockbook $* $(ARGS)
deb-%: .deb-image
docker run -t --rm -e PACKAGER=$(PACKAGER) -e UPDATE_VENDOR=$(UPDATE_VENDOR) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh all $* $(ARGS)
docker run -t --rm -e PACKAGER=$(PACKAGER) -v "$(CURDIR):/src" -v "$(CURDIR)/build:/out" $(DEB_IMAGE) /build/build-deb.sh all $* $(ARGS)
deb-blockbook-all: clean-deb $(addprefix deb-blockbook-, $(TARGETS))
@ -44,8 +45,8 @@ build-images: clean-images
.bin-image:
@if [ $$(build/tools/image_status.sh $(BIN_IMAGE):latest build/docker) != "ok" ]; then \
echo "Building image $(BIN_IMAGE)..."; \
docker build --no-cache=$(NO_CACHE) -t $(BIN_IMAGE) build/docker/bin; \
echo "Building image $(BIN_IMAGE) from $(BASE_IMAGE)"; \
docker build --no-cache=$(NO_CACHE) --build-arg TCMALLOC=$(TCMALLOC) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t $(BIN_IMAGE) build/docker/bin; \
else \
echo "Image $(BIN_IMAGE) is up to date"; \
fi

74
README-upstream.md 100644
View File

@ -0,0 +1,74 @@
[![Go Report Card](https://goreportcard.com/badge/trezor/blockbook)](https://goreportcard.com/report/trezor/blockbook)
# Blockbook
**Blockbook** is back-end service for Trezor wallet. Main features of **Blockbook** are:
- index of addresses and address balances of the connected block chain
- fast searches in the indexes
- simple blockchain explorer
- websocket, API and legacy Bitcore Insight compatible socket.io interfaces
- support of multiple coins (Bitcoin and Ethereum type), with easy extensibility for other coins
- scripts for easy creation of debian packages for backend and blockbook
## Build and installation instructions
Officially supported platform is **Debian Linux** and **AMD64** architecture.
Memory and disk requirements for initial synchronization of **Bitcoin mainnet** are around 32 GB RAM and over 180 GB of disk space. After initial synchronization, fully synchronized instance uses about 10 GB RAM.
Other coins should have lower requirements, depending on the size of their block chain. Note that fast SSD disks are highly
recommended.
User installation guide is [here](https://wiki.trezor.io/User_manual:Running_a_local_instance_of_Trezor_Wallet_backend_(Blockbook)).
Developer build guide is [here](/docs/build.md).
Contribution guide is [here](CONTRIBUTING.md).
## Implemented coins
Blockbook currently supports over 30 coins. The Trezor team implemented
- Bitcoin, Bitcoin Cash, Zcash, Dash, Litecoin, Bitcoin Gold, Ethereum, Ethereum Classic, Dogecoin, Namecoin, Vertcoin, DigiByte, Liquid
the rest of coins were implemented by the community.
Testnets for some coins are also supported, for example:
- Bitcoin Testnet, Bitcoin Cash Testnet, ZCash Testnet, Ethereum Testnet Ropsten
List of all implemented coins is in [the registry of ports](/docs/ports.md).
## Common issues when running Blockbook or implementing additional coins
#### Out of memory when doing initial synchronization
How to reduce memory footprint of the initial sync:
- disable rocksdb cache by parameter `-dbcache=0`, the default size is 500MB
- run blockbook with parameter `-workers=1`. This disables bulk import mode, which caches a lot of data in memory (not in rocksdb cache). It will run about twice as slowly but especially for smaller blockchains it is no problem at all.
Please add your experience to this [issue](https://github.com/trezor/blockbook/issues/43).
#### Error `internalState: database is in inconsistent state and cannot be used`
Blockbook was killed during the initial import, most commonly by OOM killer. By default, Blockbook performs the initial import in bulk import mode, which for performance reasons does not store all the data immediately to the database. If Blockbook is killed during this phase, the database is left in an inconsistent state.
See above how to reduce the memory footprint, delete the database files and run the import again.
Check [this](https://github.com/trezor/blockbook/issues/89) or [this](https://github.com/trezor/blockbook/issues/147) issue for more info.
#### Running on Ubuntu
[This issue](https://github.com/trezor/blockbook/issues/45) discusses how to run Blockbook on Ubuntu. If you have some additional experience with Blockbook on Ubuntu, please add it to [this issue](https://github.com/trezor/blockbook/issues/45).
#### My coin implementation is reporting parse errors when importing blockchain
Your coin's block/transaction data may not be compatible with `BitcoinParser` `ParseBlock`/`ParseTx`, which is used by default. In that case, implement your coin in a similar way we used in case of [zcash](https://github.com/trezor/blockbook/tree/master/bchain/coins/zec) and some other coins. The principle is not to parse the block/transaction data in Blockbook but instead to get parsed transactions as json from the backend.
## Data storage in RocksDB
Blockbook stores data the key-value store RocksDB. Database format is described [here](/docs/rocksdb.md).
## API
Blockbook API is described [here](/docs/api.md).

View File

@ -1,74 +1,57 @@
[![Go Report Card](https://goreportcard.com/badge/trezor/blockbook)](https://goreportcard.com/report/trezor/blockbook)
# Fork
Fork of Trezor Blockbook.
# Blockbook
**Blockbook** is back-end service for Trezor wallet. Main features of **Blockbook** are:
The differences:
- index of addresses and address balances of the connected block chain
- fast searches in the indexes
- simple blockchain explorer
- websocket, API and legacy Bitcore Insight compatible socket.io interfaces
- support of multiple coins (Bitcoin and Ethereum type), with easy extensibility for other coins
- scripts for easy creation of debian packages for backend and blockbook
* Just for Ethereum.
## Build and installation instructions
* Use existing `geth --full` server.
Officially supported platform is **Debian Linux** and **AMD64** architecture.
* Don't require `backend-*` package.
Memory and disk requirements for initial synchronization of **Bitcoin mainnet** are around 32 GB RAM and over 180 GB of disk space. After initial synchronization, fully synchronized instance uses about 10 GB RAM.
Other coins should have lower requirements, depending on the size of their block chain. Note that fast SSD disks are highly
recommended.
* Minimal UI, dark theme.
User installation guide is [here](https://wiki.trezor.io/User_manual:Running_a_local_instance_of_Trezor_Wallet_backend_(Blockbook)).
* Listen only on localhost, no SSL.
Developer build guide is [here](/docs/build.md).
* Use spacecruft repos, not github.
Contribution guide is [here](CONTRIBUTING.md).
* Don't use CDN.
## Implemented coins
# Install
Blockbook currently supports over 30 coins. The Trezor team implemented
```
# Install docker, etc.
git clone https://spacecruft.org/spacecruft/blockbook
cd blockbook
make deb-blockbook-ethereum
dpkg -i build/blockbook-ethereum_0.3.4_amd64.deb
```
- Bitcoin, Bitcoin Cash, Zcash, Dash, Litecoin, Bitcoin Gold, Ethereum, Ethereum Classic, Dogecoin, Namecoin, Vertcoin, DigiByte, Liquid
Edit config:
```
vim /opt/coins/blockbook/ethereum/config/blockchaincfg.json
```
the rest of coins were implemented by the community.
XXX Hardcoded into systemd script, set `geth` node:
Testnets for some coins are also supported, for example:
- Bitcoin Testnet, Bitcoin Cash Testnet, ZCash Testnet, Ethereum Testnet Ropsten
```
vim /lib/systemd/system/blockbook-ethereum.service
systemctl daemon-reload
```
List of all implemented coins is in [the registry of ports](/docs/ports.md).
Start:
```
systemctl start blockbook-ethereum.service
```
## Common issues when running Blockbook or implementing additional coins
Logs:
```
tail -f /opt/coins/blockbook/ethereum/logs/blockbook.INFO
```
#### Out of memory when doing initial synchronization
# Upstream
Fork of Trezor Blockbook. See `README-upstream.md`.
How to reduce memory footprint of the initial sync:
* https://github.com/trezor/blockbook
- disable rocksdb cache by parameter `-dbcache=0`, the default size is 500MB
- run blockbook with parameter `-workers=1`. This disables bulk import mode, which caches a lot of data in memory (not in rocksdb cache). It will run about twice as slowly but especially for smaller blockchains it is no problem at all.
Please add your experience to this [issue](https://github.com/trezor/blockbook/issues/43).
#### Error `internalState: database is in inconsistent state and cannot be used`
Blockbook was killed during the initial import, most commonly by OOM killer. By default, Blockbook performs the initial import in bulk import mode, which for performance reasons does not store all the data immediately to the database. If Blockbook is killed during this phase, the database is left in an inconsistent state.
See above how to reduce the memory footprint, delete the database files and run the import again.
Check [this](https://github.com/trezor/blockbook/issues/89) or [this](https://github.com/trezor/blockbook/issues/147) issue for more info.
#### Running on Ubuntu
[This issue](https://github.com/trezor/blockbook/issues/45) discusses how to run Blockbook on Ubuntu. If you have some additional experience with Blockbook on Ubuntu, please add it to [this issue](https://github.com/trezor/blockbook/issues/45).
#### My coin implementation is reporting parse errors when importing blockchain
Your coin's block/transaction data may not be compatible with `BitcoinParser` `ParseBlock`/`ParseTx`, which is used by default. In that case, implement your coin in a similar way we used in case of [zcash](https://github.com/trezor/blockbook/tree/master/bchain/coins/zec) and some other coins. The principle is not to parse the block/transaction data in Blockbook but instead to get parsed transactions as json from the backend.
## Data storage in RocksDB
Blockbook stores data the key-value store RocksDB. Database format is described [here](/docs/rocksdb.md).
## API
Blockbook API is described [here](/docs/api.md).

View File

@ -7,9 +7,10 @@ import (
"sort"
"time"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/common"
"github.com/trezor/blockbook/db"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/eth"
"spacecruft.org/spacecruft/blockbook/common"
"spacecruft.org/spacecruft/blockbook/db"
)
const maxUint32 = ^uint32(0)
@ -170,12 +171,12 @@ type TokenTransfer struct {
// EthereumSpecific contains ethereum specific transaction data
type EthereumSpecific struct {
Status int `json:"status"` // 1 OK, 0 Fail, -1 pending
Nonce uint64 `json:"nonce"`
GasLimit *big.Int `json:"gasLimit"`
GasUsed *big.Int `json:"gasUsed"`
GasPrice *Amount `json:"gasPrice"`
Data string `json:"data,omitempty"`
Status eth.TxStatus `json:"status"` // 1 OK, 0 Fail, -1 pending
Nonce uint64 `json:"nonce"`
GasLimit *big.Int `json:"gasLimit"`
GasUsed *big.Int `json:"gasUsed"`
GasPrice *Amount `json:"gasPrice"`
Data string `json:"data,omitempty"`
}
// Tx holds information about a transaction
@ -195,8 +196,7 @@ type Tx struct {
FeesSat *Amount `json:"fees,omitempty"`
Hex string `json:"hex,omitempty"`
Rbf bool `json:"rbf,omitempty"`
CoinSpecificData interface{} `json:"-"`
CoinSpecificJSON json.RawMessage `json:"-"`
CoinSpecificData json.RawMessage `json:"coinSpecificData,omitempty"`
TokenTransfers []TokenTransfer `json:"tokenTransfers,omitempty"`
EthereumSpecific *EthereumSpecific `json:"ethereumSpecific,omitempty"`
}
@ -226,6 +226,8 @@ const (
AddressFilterVoutInputs = -2
// AddressFilterVoutOutputs specifies that only txs where the address is as output are returned
AddressFilterVoutOutputs = -3
// AddressFilterVoutQueryNotNecessary signals that query for transactions is not necessary as there are no transactions for specified contract filter
AddressFilterVoutQueryNotNecessary = -4
// TokensToReturnNonzeroBalance - return only tokens with nonzero balance
TokensToReturnNonzeroBalance TokensToReturn = 0
@ -301,12 +303,13 @@ func (a Utxos) Less(i, j int) bool {
// BalanceHistory contains info about one point in time of balance history
type BalanceHistory struct {
Time uint32 `json:"time"`
Txs uint32 `json:"txs"`
ReceivedSat *Amount `json:"received"`
SentSat *Amount `json:"sent"`
FiatRates map[string]float64 `json:"rates,omitempty"`
Txid string `json:"txid,omitempty"`
Time uint32 `json:"time"`
Txs uint32 `json:"txs"`
ReceivedSat *Amount `json:"received"`
SentSat *Amount `json:"sent"`
SentToSelfSat *Amount `json:"sentToSelf"`
FiatRates map[string]float64 `json:"rates,omitempty"`
Txid string `json:"txid,omitempty"`
}
// BalanceHistories is array of BalanceHistory
@ -328,8 +331,9 @@ func (a BalanceHistories) SortAndAggregate(groupByTime uint32) BalanceHistories
bhs := make(BalanceHistories, 0)
if len(a) > 0 {
bha := BalanceHistory{
SentSat: &Amount{},
ReceivedSat: &Amount{},
ReceivedSat: &Amount{},
SentSat: &Amount{},
SentToSelfSat: &Amount{},
}
sort.Sort(a)
for i := range a {
@ -342,17 +346,19 @@ func (a BalanceHistories) SortAndAggregate(groupByTime uint32) BalanceHistories
bhs = append(bhs, bha)
}
bha = BalanceHistory{
Time: time,
SentSat: &Amount{},
ReceivedSat: &Amount{},
Time: time,
ReceivedSat: &Amount{},
SentSat: &Amount{},
SentToSelfSat: &Amount{},
}
}
if bha.Txid != bh.Txid {
bha.Txs += bh.Txs
bha.Txid = bh.Txid
}
(*big.Int)(bha.SentSat).Add((*big.Int)(bha.SentSat), (*big.Int)(bh.SentSat))
(*big.Int)(bha.ReceivedSat).Add((*big.Int)(bha.ReceivedSat), (*big.Int)(bh.ReceivedSat))
(*big.Int)(bha.SentSat).Add((*big.Int)(bha.SentSat), (*big.Int)(bh.SentSat))
(*big.Int)(bha.SentToSelfSat).Add((*big.Int)(bha.SentToSelfSat), (*big.Int)(bh.SentToSelfSat))
}
if bha.Txs > 0 {
bha.Txid = ""
@ -415,26 +421,10 @@ type BlockbookInfo struct {
About string `json:"about"`
}
// BackendInfo is used to get information about blockchain
type BackendInfo struct {
BackendError string `json:"error,omitempty"`
Chain string `json:"chain,omitempty"`
Blocks int `json:"blocks,omitempty"`
Headers int `json:"headers,omitempty"`
BestBlockHash string `json:"bestBlockHash,omitempty"`
Difficulty string `json:"difficulty,omitempty"`
SizeOnDisk int64 `json:"sizeOnDisk,omitempty"`
Version string `json:"version,omitempty"`
Subversion string `json:"subversion,omitempty"`
ProtocolVersion string `json:"protocolVersion,omitempty"`
Timeoffset float64 `json:"timeOffset,omitempty"`
Warnings string `json:"warnings,omitempty"`
}
// SystemInfo contains information about the running blockbook and backend instance
type SystemInfo struct {
Blockbook *BlockbookInfo `json:"blockbook"`
Backend *BackendInfo `json:"backend"`
Blockbook *BlockbookInfo `json:"blockbook"`
Backend *common.BackendInfo `json:"backend"`
}
// MempoolTxid contains information about a transaction in mempool

View File

@ -67,20 +67,22 @@ func TestBalanceHistories_SortAndAggregate(t *testing.T) {
name: "one",
a: []BalanceHistory{
{
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
Time: 1521514812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
SentToSelfSat: (*Amount)(big.NewInt(1)),
Time: 1521514812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
},
},
groupByTime: 3600,
want: []BalanceHistory{
{
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
Time: 1521514800,
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
SentToSelfSat: (*Amount)(big.NewInt(1)),
Time: 1521514800,
Txs: 1,
},
},
},
@ -88,67 +90,76 @@ func TestBalanceHistories_SortAndAggregate(t *testing.T) {
name: "aggregate",
a: []BalanceHistory{
{
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
Time: 1521504812,
Txid: "0011223344556677889900112233445566778899001122334455667788990011",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(1)),
SentSat: (*Amount)(big.NewInt(2)),
SentToSelfSat: (*Amount)(big.NewInt(0)),
Time: 1521504812,
Txid: "0011223344556677889900112233445566778899001122334455667788990011",
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(3)),
SentSat: (*Amount)(big.NewInt(4)),
Time: 1521504812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(3)),
SentSat: (*Amount)(big.NewInt(4)),
SentToSelfSat: (*Amount)(big.NewInt(2)),
Time: 1521504812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(5)),
SentSat: (*Amount)(big.NewInt(6)),
Time: 1521514812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(5)),
SentSat: (*Amount)(big.NewInt(6)),
SentToSelfSat: (*Amount)(big.NewInt(3)),
Time: 1521514812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(7)),
SentSat: (*Amount)(big.NewInt(8)),
Time: 1521504812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(7)),
SentSat: (*Amount)(big.NewInt(8)),
SentToSelfSat: (*Amount)(big.NewInt(3)),
Time: 1521504812,
Txid: "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840",
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(9)),
SentSat: (*Amount)(big.NewInt(10)),
Time: 1521534812,
Txid: "0011223344556677889900112233445566778899001122334455667788990011",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(9)),
SentSat: (*Amount)(big.NewInt(10)),
SentToSelfSat: (*Amount)(big.NewInt(5)),
Time: 1521534812,
Txid: "0011223344556677889900112233445566778899001122334455667788990011",
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(11)),
SentSat: (*Amount)(big.NewInt(12)),
Time: 1521534812,
Txid: "1122334455667788990011223344556677889900112233445566778899001100",
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(11)),
SentSat: (*Amount)(big.NewInt(12)),
SentToSelfSat: (*Amount)(big.NewInt(6)),
Time: 1521534812,
Txid: "1122334455667788990011223344556677889900112233445566778899001100",
Txs: 1,
},
},
groupByTime: 3600,
want: []BalanceHistory{
{
ReceivedSat: (*Amount)(big.NewInt(11)),
SentSat: (*Amount)(big.NewInt(14)),
Time: 1521504000,
Txs: 2,
ReceivedSat: (*Amount)(big.NewInt(11)),
SentSat: (*Amount)(big.NewInt(14)),
SentToSelfSat: (*Amount)(big.NewInt(5)),
Time: 1521504000,
Txs: 2,
},
{
ReceivedSat: (*Amount)(big.NewInt(5)),
SentSat: (*Amount)(big.NewInt(6)),
Time: 1521514800,
Txs: 1,
ReceivedSat: (*Amount)(big.NewInt(5)),
SentSat: (*Amount)(big.NewInt(6)),
SentToSelfSat: (*Amount)(big.NewInt(3)),
Time: 1521514800,
Txs: 1,
},
{
ReceivedSat: (*Amount)(big.NewInt(20)),
SentSat: (*Amount)(big.NewInt(22)),
Time: 1521532800,
Txs: 2,
ReceivedSat: (*Amount)(big.NewInt(20)),
SentSat: (*Amount)(big.NewInt(22)),
SentToSelfSat: (*Amount)(big.NewInt(11)),
Time: 1521532800,
Txs: 2,
},
},
},

View File

@ -3,7 +3,7 @@ package api
import (
"math/big"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
)
// ScriptSigV1 is used for legacy api v1

View File

@ -14,10 +14,10 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/eth"
"github.com/trezor/blockbook/common"
"github.com/trezor/blockbook/db"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/eth"
"spacecruft.org/spacecruft/blockbook/common"
"spacecruft.org/spacecruft/blockbook/db"
)
// Worker is handle to api worker
@ -253,32 +253,7 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height int, spe
if err != nil {
glog.Errorf("GetErc20FromTx error %v, %v", err, bchainTx)
}
tokens = make([]TokenTransfer, len(ets))
for i := range ets {
e := &ets[i]
cd, err := w.chainParser.GetAddrDescFromAddress(e.Contract)
if err != nil {
glog.Errorf("GetAddrDescFromAddress error %v, contract %v", err, e.Contract)
continue
}
erc20c, err := w.chain.EthereumTypeGetErc20ContractInfo(cd)
if err != nil {
glog.Errorf("GetErc20ContractInfo error %v, contract %v", err, e.Contract)
}
if erc20c == nil {
erc20c = &bchain.Erc20Contract{Name: e.Contract}
}
tokens[i] = TokenTransfer{
Type: ERC20TokenType,
Token: e.Contract,
From: e.From,
To: e.To,
Decimals: erc20c.Decimals,
Value: (*Amount)(&e.Tokens),
Name: erc20c.Name,
Symbol: erc20c.Symbol,
}
}
tokens = w.getTokensFromErc20(ets)
ethTxData := eth.GetEthereumTxData(bchainTx)
// mempool txs do not have fees yet
if ethTxData.GasUsed != nil {
@ -299,7 +274,8 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height int, spe
// for now do not return size, we would have to compute vsize of segwit transactions
// size:=len(bchainTx.Hex) / 2
var sj json.RawMessage
if specificJSON {
// return CoinSpecificData for all mempool transactions or if requested
if specificJSON || bchainTx.Confirmations == 0 {
sj, err = w.chain.GetTransactionSpecific(bchainTx)
if err != nil {
return nil, err
@ -324,14 +300,140 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height int, spe
Rbf: rbf,
Vin: vins,
Vout: vouts,
CoinSpecificData: bchainTx.CoinSpecificData,
CoinSpecificJSON: sj,
CoinSpecificData: sj,
TokenTransfers: tokens,
EthereumSpecific: ethSpecific,
}
return r, nil
}
// GetTransactionFromMempoolTx converts bchain.MempoolTx to Tx, with limited amount of data
// it is not doing any request to backend or to db
func (w *Worker) GetTransactionFromMempoolTx(mempoolTx *bchain.MempoolTx) (*Tx, error) {
var err error
var valInSat, valOutSat, feesSat big.Int
var pValInSat *big.Int
var tokens []TokenTransfer
var ethSpecific *EthereumSpecific
vins := make([]Vin, len(mempoolTx.Vin))
rbf := false
for i := range mempoolTx.Vin {
bchainVin := &mempoolTx.Vin[i]
vin := &vins[i]
vin.Txid = bchainVin.Txid
vin.N = i
vin.Vout = bchainVin.Vout
vin.Sequence = int64(bchainVin.Sequence)
// detect explicit Replace-by-Fee transactions as defined by BIP125
if bchainVin.Sequence < 0xffffffff-1 {
rbf = true
}
vin.Hex = bchainVin.ScriptSig.Hex
vin.Coinbase = bchainVin.Coinbase
if w.chainType == bchain.ChainBitcoinType {
// bchainVin.Txid=="" is coinbase transaction
if bchainVin.Txid != "" {
vin.ValueSat = (*Amount)(&bchainVin.ValueSat)
vin.AddrDesc = bchainVin.AddrDesc
vin.Addresses, vin.IsAddress, _ = w.chainParser.GetAddressesFromAddrDesc(vin.AddrDesc)
if vin.ValueSat != nil {
valInSat.Add(&valInSat, (*big.Int)(vin.ValueSat))
}
}
} else if w.chainType == bchain.ChainEthereumType {
if len(bchainVin.Addresses) > 0 {
vin.AddrDesc, err = w.chainParser.GetAddrDescFromAddress(bchainVin.Addresses[0])
if err != nil {
glog.Errorf("GetAddrDescFromAddress error %v, tx %v, bchainVin %v", err, mempoolTx.Txid, bchainVin)
}
vin.Addresses = bchainVin.Addresses
vin.IsAddress = true
}
}
}
vouts := make([]Vout, len(mempoolTx.Vout))
for i := range mempoolTx.Vout {
bchainVout := &mempoolTx.Vout[i]
vout := &vouts[i]
vout.N = i
vout.ValueSat = (*Amount)(&bchainVout.ValueSat)
valOutSat.Add(&valOutSat, &bchainVout.ValueSat)
vout.Hex = bchainVout.ScriptPubKey.Hex
vout.AddrDesc, vout.Addresses, vout.IsAddress, err = w.getAddressesFromVout(bchainVout)
if err != nil {
glog.V(2).Infof("getAddressesFromVout error %v, %v, output %v", err, mempoolTx.Txid, bchainVout.N)
}
}
if w.chainType == bchain.ChainBitcoinType {
// for coinbase transactions valIn is 0
feesSat.Sub(&valInSat, &valOutSat)
if feesSat.Sign() == -1 {
feesSat.SetUint64(0)
}
pValInSat = &valInSat
} else if w.chainType == bchain.ChainEthereumType {
if len(mempoolTx.Vout) > 0 {
valOutSat = mempoolTx.Vout[0].ValueSat
}
tokens = w.getTokensFromErc20(mempoolTx.Erc20)
ethTxData := eth.GetEthereumTxDataFromSpecificData(mempoolTx.CoinSpecificData)
ethSpecific = &EthereumSpecific{
GasLimit: ethTxData.GasLimit,
GasPrice: (*Amount)(ethTxData.GasPrice),
GasUsed: ethTxData.GasUsed,
Nonce: ethTxData.Nonce,
Status: ethTxData.Status,
Data: ethTxData.Data,
}
}
r := &Tx{
Blocktime: mempoolTx.Blocktime,
FeesSat: (*Amount)(&feesSat),
Locktime: mempoolTx.LockTime,
Txid: mempoolTx.Txid,
ValueInSat: (*Amount)(pValInSat),
ValueOutSat: (*Amount)(&valOutSat),
Version: mempoolTx.Version,
Hex: mempoolTx.Hex,
Rbf: rbf,
Vin: vins,
Vout: vouts,
TokenTransfers: tokens,
EthereumSpecific: ethSpecific,
}
return r, nil
}
func (w *Worker) getTokensFromErc20(erc20 []bchain.Erc20Transfer) []TokenTransfer {
tokens := make([]TokenTransfer, len(erc20))
for i := range erc20 {
e := &erc20[i]
cd, err := w.chainParser.GetAddrDescFromAddress(e.Contract)
if err != nil {
glog.Errorf("GetAddrDescFromAddress error %v, contract %v", err, e.Contract)
continue
}
erc20c, err := w.chain.EthereumTypeGetErc20ContractInfo(cd)
if err != nil {
glog.Errorf("GetErc20ContractInfo error %v, contract %v", err, e.Contract)
}
if erc20c == nil {
erc20c = &bchain.Erc20Contract{Name: e.Contract}
}
tokens[i] = TokenTransfer{
Type: ERC20TokenType,
Token: e.Contract,
From: e.From,
To: e.To,
Decimals: erc20c.Decimals,
Value: (*Amount)(&e.Tokens),
Name: erc20c.Name,
Symbol: erc20c.Symbol,
}
}
return tokens
}
func (w *Worker) getAddressTxids(addrDesc bchain.AddressDescriptor, mempool bool, filter *AddressFilter, maxResults int) ([]string, error) {
var err error
txids := make([]string, 0, 4)
@ -401,6 +503,19 @@ func (t *Tx) getAddrVoutValue(addrDesc bchain.AddressDescriptor) *big.Int {
}
return &val
}
func (t *Tx) getAddrEthereumTypeMempoolInputValue(addrDesc bchain.AddressDescriptor) *big.Int {
var val big.Int
if len(t.Vin) > 0 && len(t.Vout) > 0 && bytes.Equal(t.Vin[0].AddrDesc, addrDesc) {
val.Add(&val, (*big.Int)(t.Vout[0].ValueSat))
// add maximum possible fee (the used value is not yet known)
if t.EthereumSpecific != nil && t.EthereumSpecific.GasLimit != nil && t.EthereumSpecific.GasPrice != nil {
var fees big.Int
fees.Mul((*big.Int)(t.EthereumSpecific.GasPrice), t.EthereumSpecific.GasLimit)
val.Add(&val, &fees)
}
}
return &val
}
func (t *Tx) getAddrVinValue(addrDesc bchain.AddressDescriptor) *big.Int {
var val big.Int
@ -497,6 +612,44 @@ func computePaging(count, page, itemsOnPage int) (Paging, int, int, int) {
}, from, to, page
}
func (w *Worker) getEthereumToken(index int, addrDesc, contract bchain.AddressDescriptor, details AccountDetails, txs int) (*Token, error) {
var b *big.Int
validContract := true
ci, err := w.chain.EthereumTypeGetErc20ContractInfo(contract)
if err != nil {
return nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractInfo %v", contract)
}
if ci == nil {
ci = &bchain.Erc20Contract{}
addresses, _, _ := w.chainParser.GetAddressesFromAddrDesc(contract)
if len(addresses) > 0 {
ci.Contract = addresses[0]
ci.Name = addresses[0]
}
validContract = false
}
// do not read contract balances etc in case of Basic option
if details >= AccountDetailsTokenBalances && validContract {
b, err = w.chain.EthereumTypeGetErc20ContractBalance(addrDesc, contract)
if err != nil {
// return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractBalance %v %v", addrDesc, c.Contract)
glog.Warningf("EthereumTypeGetErc20ContractBalance addr %v, contract %v, %v", addrDesc, contract, err)
}
} else {
b = nil
}
return &Token{
Type: ERC20TokenType,
BalanceSat: (*Amount)(b),
Contract: ci.Contract,
Name: ci.Name,
Symbol: ci.Symbol,
Transfers: txs,
Decimals: ci.Decimals,
ContractIndex: strconv.Itoa(index),
}, nil
}
func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescriptor, details AccountDetails, filter *AddressFilter) (*db.AddrBalance, []Token, *bchain.Erc20Contract, uint64, int, int, error) {
var (
ba *db.AddrBalance
@ -515,6 +668,13 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto
if err != nil {
return nil, nil, nil, 0, 0, 0, errors.Annotatef(err, "EthereumTypeGetBalance %v", addrDesc)
}
var filterDesc bchain.AddressDescriptor
if filter.Contract != "" {
filterDesc, err = w.chainParser.GetAddrDescFromAddress(filter.Contract)
if err != nil {
return nil, nil, nil, 0, 0, 0, NewAPIError(fmt.Sprintf("Invalid contract filter, %v", err), true)
}
}
if ca != nil {
ba = &db.AddrBalance{
Txs: uint32(ca.TotalTxs),
@ -526,13 +686,6 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto
if err != nil {
return nil, nil, nil, 0, 0, 0, errors.Annotatef(err, "EthereumTypeGetNonce %v", addrDesc)
}
var filterDesc bchain.AddressDescriptor
if filter.Contract != "" {
filterDesc, err = w.chainParser.GetAddrDescFromAddress(filter.Contract)
if err != nil {
return nil, nil, nil, 0, 0, 0, NewAPIError(fmt.Sprintf("Invalid contract filter, %v", err), true)
}
}
if details > AccountDetailsBasic {
tokens = make([]Token, len(ca.Contracts))
var j int
@ -544,43 +697,26 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto
// filter only transactions of this contract
filter.Vout = i + 1
}
validContract := true
ci, err := w.chain.EthereumTypeGetErc20ContractInfo(c.Contract)
t, err := w.getEthereumToken(i+1, addrDesc, c.Contract, details, int(c.Txs))
if err != nil {
return nil, nil, nil, 0, 0, 0, errors.Annotatef(err, "EthereumTypeGetErc20ContractInfo %v", c.Contract)
}
if ci == nil {
ci = &bchain.Erc20Contract{}
addresses, _, _ := w.chainParser.GetAddressesFromAddrDesc(c.Contract)
if len(addresses) > 0 {
ci.Contract = addresses[0]
ci.Name = addresses[0]
}
validContract = false
}
// do not read contract balances etc in case of Basic option
if details >= AccountDetailsTokenBalances && validContract {
b, err = w.chain.EthereumTypeGetErc20ContractBalance(addrDesc, c.Contract)
if err != nil {
// return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractBalance %v %v", addrDesc, c.Contract)
glog.Warningf("EthereumTypeGetErc20ContractBalance addr %v, contract %v, %v", addrDesc, c.Contract, err)
}
} else {
b = nil
}
tokens[j] = Token{
Type: ERC20TokenType,
BalanceSat: (*Amount)(b),
Contract: ci.Contract,
Name: ci.Name,
Symbol: ci.Symbol,
Transfers: int(c.Txs),
Decimals: ci.Decimals,
ContractIndex: strconv.Itoa(i + 1),
return nil, nil, nil, 0, 0, 0, err
}
tokens[j] = *t
j++
}
tokens = tokens[:j]
// special handling if filter has contract
// if the address has no transactions with given contract, check the balance, the address may have some balance even without transactions
if len(filterDesc) > 0 && j == 0 && details >= AccountDetailsTokens {
t, err := w.getEthereumToken(0, addrDesc, filterDesc, details, 0)
if err != nil {
return nil, nil, nil, 0, 0, 0, err
}
tokens = []Token{*t}
// switch off query for transactions, there are no transactions
filter.Vout = AddressFilterVoutQueryNotNecessary
} else {
tokens = tokens[:j]
}
}
ci, err = w.chain.EthereumTypeGetErc20ContractInfo(addrDesc)
if err != nil {
@ -594,6 +730,8 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto
totalResults = int(ca.NonContractTxs)
} else if filter.Vout > 0 && filter.Vout-1 < len(ca.Contracts) {
totalResults = int(ca.Contracts[filter.Vout-1].Txs)
} else if filter.Vout == AddressFilterVoutQueryNotNecessary {
totalResults = 0
}
}
nonContractTxs = int(ca.NonContractTxs)
@ -604,6 +742,16 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto
BalanceSat: *b,
}
}
// special handling if filtering for a contract, check the ballance of it
if len(filterDesc) > 0 && details >= AccountDetailsTokens {
t, err := w.getEthereumToken(0, addrDesc, filterDesc, details, 0)
if err != nil {
return nil, nil, nil, 0, 0, 0, err
}
tokens = []Token{*t}
// switch off query for transactions, there are no transactions
filter.Vout = AddressFilterVoutQueryNotNecessary
}
}
return ba, tokens, ci, n, nonContractTxs, totalResults, nil
}
@ -620,7 +768,7 @@ func (w *Worker) txFromTxid(txid string, bestheight uint32, option AccountDetail
if ta == nil {
glog.Warning("DB inconsistency: tx ", txid, ": not found in txAddresses")
// as fallback, get tx from backend
tx, err = w.GetTransaction(txid, false, true)
tx, err = w.GetTransaction(txid, false, false)
if err != nil {
return nil, errors.Annotatef(err, "GetTransaction %v", txid)
}
@ -639,7 +787,7 @@ func (w *Worker) txFromTxid(txid string, bestheight uint32, option AccountDetail
tx = w.txFromTxAddress(txid, ta, blockInfo, bestheight)
}
} else {
tx, err = w.GetTransaction(txid, false, true)
tx, err = w.GetTransaction(txid, false, false)
if err != nil {
return nil, errors.Annotatef(err, "GetTransaction %v", txid)
}
@ -728,7 +876,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco
return nil, errors.Annotatef(err, "getAddressTxids %v true", addrDesc)
}
for _, txid := range txm {
tx, err := w.GetTransaction(txid, false, false)
tx, err := w.GetTransaction(txid, false, true)
// mempool transaction may fail
if err != nil || tx == nil {
glog.Warning("GetTransaction in mempool: ", err)
@ -737,7 +885,12 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco
if tx.Confirmations == 0 {
unconfirmedTxs++
uBalSat.Add(&uBalSat, tx.getAddrVoutValue(addrDesc))
uBalSat.Sub(&uBalSat, tx.getAddrVinValue(addrDesc))
// ethereum has a different logic - value not in input and add maximum possible fees
if w.chainType == bchain.ChainEthereumType {
uBalSat.Sub(&uBalSat, tx.getAddrEthereumTypeMempoolInputValue(addrDesc))
} else {
uBalSat.Sub(&uBalSat, tx.getAddrVinValue(addrDesc))
}
if page == 0 {
if option == AccountDetailsTxidHistory {
txids = append(txids, tx.Txid)
@ -750,7 +903,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco
}
}
// get tx history if requested by option or check mempool if there are some transactions for a new address
if option >= AccountDetailsTxidHistory {
if option >= AccountDetailsTxidHistory && filter.Vout != AddressFilterVoutQueryNotNecessary {
txc, err := w.getAddressTxids(addrDesc, false, filter, (page+1)*txsOnPage)
if err != nil {
return nil, errors.Annotatef(err, "getAddressTxids %v false", addrDesc)
@ -821,7 +974,7 @@ func (w *Worker) balanceHistoryHeightsFromTo(fromTimestamp, toTimestamp int64) (
return fromUnix, fromHeight, toUnix, toHeight
}
func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid string, fromUnix, toUnix uint32) (*BalanceHistory, error) {
func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid string, fromUnix, toUnix uint32, selfAddrDesc map[string]struct{}) (*BalanceHistory, error) {
var time uint32
var err error
var ta *db.TxAddresses
@ -854,17 +1007,30 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s
return nil, nil
}
bh := BalanceHistory{
Time: time,
Txs: 1,
SentSat: &Amount{},
ReceivedSat: &Amount{},
Txid: txid,
Time: time,
Txs: 1,
ReceivedSat: &Amount{},
SentSat: &Amount{},
SentToSelfSat: &Amount{},
Txid: txid,
}
countSentToSelf := false
if w.chainType == bchain.ChainBitcoinType {
// detect if this input is the first of selfAddrDesc
// to not to count sentToSelf multiple times if counting multiple xpub addresses
ownInputIndex := -1
for i := range ta.Inputs {
tai := &ta.Inputs[i]
if _, found := selfAddrDesc[string(tai.AddrDesc)]; found {
if ownInputIndex < 0 {
ownInputIndex = i
}
}
if bytes.Equal(addrDesc, tai.AddrDesc) {
(*big.Int)(bh.SentSat).Add((*big.Int)(bh.SentSat), &tai.ValueSat)
if ownInputIndex == i {
countSentToSelf = true
}
}
}
for i := range ta.Outputs {
@ -872,12 +1038,17 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s
if bytes.Equal(addrDesc, tao.AddrDesc) {
(*big.Int)(bh.ReceivedSat).Add((*big.Int)(bh.ReceivedSat), &tao.ValueSat)
}
if countSentToSelf {
if _, found := selfAddrDesc[string(tao.AddrDesc)]; found {
(*big.Int)(bh.SentToSelfSat).Add((*big.Int)(bh.SentToSelfSat), &tao.ValueSat)
}
}
}
} else if w.chainType == bchain.ChainEthereumType {
var value big.Int
ethTxData := eth.GetEthereumTxData(bchainTx)
// add received amount only for OK transactions
if ethTxData.Status == 1 {
// add received amount only for OK or unknown status (old) transactions
if ethTxData.Status == eth.TxStatusOK || ethTxData.Status == eth.TxStatusUnknown {
if len(bchainTx.Vout) > 0 {
bchainVout := &bchainTx.Vout[0]
value = bchainVout.ValueSat
@ -889,6 +1060,9 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s
if bytes.Equal(addrDesc, txAddrDesc) {
(*big.Int)(bh.ReceivedSat).Add((*big.Int)(bh.ReceivedSat), &value)
}
if _, found := selfAddrDesc[string(txAddrDesc)]; found {
countSentToSelf = true
}
}
}
}
@ -900,9 +1074,14 @@ func (w *Worker) balanceHistoryForTxid(addrDesc bchain.AddressDescriptor, txid s
return nil, err
}
if bytes.Equal(addrDesc, txAddrDesc) {
// add sent amount only for OK transactions, however fees always
if ethTxData.Status == 1 {
// add received amount only for OK or unknown status (old) transactions, fees always
if ethTxData.Status == eth.TxStatusOK || ethTxData.Status == eth.TxStatusUnknown {
(*big.Int)(bh.SentSat).Add((*big.Int)(bh.SentSat), &value)
if countSentToSelf {
if _, found := selfAddrDesc[string(txAddrDesc)]; found {
(*big.Int)(bh.SentToSelfSat).Add((*big.Int)(bh.SentToSelfSat), &value)
}
}
}
var feesSat big.Int
// mempool txs do not have fees yet
@ -963,8 +1142,9 @@ func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp in
if err != nil {
return nil, err
}
selfAddrDesc := map[string]struct{}{string(addrDesc): {}}
for txi := len(txs) - 1; txi >= 0; txi-- {
bh, err := w.balanceHistoryForTxid(addrDesc, txs[txi], fromUnix, toUnix)
bh, err := w.balanceHistoryForTxid(addrDesc, txs[txi], fromUnix, toUnix, selfAddrDesc)
if err != nil {
return nil, err
}
@ -1594,7 +1774,7 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) {
DbColumns: columnStats,
About: Text.BlockbookAbout,
}
backendInfo := &BackendInfo{
backendInfo := &common.BackendInfo{
BackendError: backendError,
BestBlockHash: ci.Bestblockhash,
Blocks: ci.Blocks,
@ -1607,7 +1787,9 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) {
Timeoffset: ci.Timeoffset,
Version: ci.Version,
Warnings: ci.Warnings,
Consensus: ci.Consensus,
}
w.is.SetBackendInfo(backendInfo)
glog.Info("GetSystemInfo finished in ", time.Since(start))
return &SystemInfo{blockbookInfo, backendInfo}, nil
}

View File

@ -9,8 +9,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/db"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/db"
)
const defaultAddressesGap = 20
@ -416,7 +416,7 @@ func (w *Worker) GetXpubAddress(xpub string, page int, txsOnPage int, option Acc
// the same tx can have multiple addresses from the same xpub, get it from backend it only once
tx, foundTx := txmMap[txid.txid]
if !foundTx {
tx, err = w.GetTransaction(txid.txid, false, false)
tx, err = w.GetTransaction(txid.txid, false, true)
// mempool transaction may fail
if err != nil || tx == nil {
glog.Warning("GetTransaction in mempool: ", err)
@ -606,12 +606,18 @@ func (w *Worker) GetXpubBalanceHistory(xpub string, fromTimestamp, toTimestamp i
if err != nil {
return nil, err
}
selfAddrDesc := make(map[string]struct{})
for _, da := range [][]xpubAddress{data.addresses, data.changeAddresses} {
for i := range da {
selfAddrDesc[string(da[i].addrDesc)] = struct{}{}
}
}
for _, da := range [][]xpubAddress{data.addresses, data.changeAddresses} {
for i := range da {
ad := &da[i]
txids := ad.txids
for txi := len(txids) - 1; txi >= 0; txi-- {
bh, err := w.balanceHistoryForTxid(ad.addrDesc, txids[txi].txid, fromUnix, toUnix)
bh, err := w.balanceHistoryForTxid(ad.addrDesc, txids[txi].txid, fromUnix, toUnix, selfAddrDesc)
if err != nil {
return nil, err
}

View File

@ -3,6 +3,7 @@ package bchain
import (
"sort"
"sync"
"time"
)
type addrIndex struct {
@ -27,6 +28,7 @@ type BaseMempool struct {
txEntries map[string]txEntry
addrDescToTx map[string][]Outpoint
OnNewTxAddr OnNewTxAddrFunc
OnNewTx OnNewTxFunc
}
// GetTransactions returns slice of mempool transactions for given address
@ -113,3 +115,22 @@ func (m *BaseMempool) GetTransactionTime(txid string) uint32 {
}
return e.time
}
func (m *BaseMempool) txToMempoolTx(tx *Tx) *MempoolTx {
mtx := MempoolTx{
Hex: tx.Hex,
Blocktime: time.Now().Unix(),
LockTime: tx.LockTime,
Txid: tx.Txid,
Version: tx.Version,
Vout: tx.Vout,
CoinSpecificData: tx.CoinSpecificData,
}
mtx.Vin = make([]MempoolVin, len(tx.Vin))
for i, vin := range tx.Vin {
mtx.Vin[i] = MempoolVin{
Vin: vin,
}
}
return &mtx
}

View File

@ -9,7 +9,7 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/common"
)
// BaseParser implements data parsing/handling functionality base for all other parsers

View File

@ -6,7 +6,7 @@ import (
"math/big"
"testing"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/common"
)
func NewBaseParser(adp int) *BaseParser {

View File

@ -8,8 +8,8 @@ import (
"github.com/martinboehm/btcutil/chaincfg"
"github.com/martinboehm/btcutil/txscript"
"github.com/schancel/cashaddr-converter/address"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// AddressFormat type is used to specify different formats of address

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -8,8 +8,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/martinboehm/bchutil"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// BCashRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package bellcoin
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// BellcoinRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,8 +3,8 @@ package bitcore
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// BitcoreRPC is an interface to JSON-RPC bitcoind service.

View File

@ -1,7 +1,7 @@
package bitzeny
import (
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"

View File

@ -9,8 +9,8 @@ import (
"reflect"
"testing"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"github.com/martinboehm/btcutil/chaincfg"
)

View File

@ -3,8 +3,8 @@ package bitzeny
import (
"encoding/json"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"github.com/golang/glog"
)

View File

@ -10,47 +10,48 @@ import (
"time"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/bch"
"github.com/trezor/blockbook/bchain/coins/bellcoin"
"github.com/trezor/blockbook/bchain/coins/bitcore"
"github.com/trezor/blockbook/bchain/coins/bitzeny"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/btg"
"github.com/trezor/blockbook/bchain/coins/cpuchain"
"github.com/trezor/blockbook/bchain/coins/dash"
"github.com/trezor/blockbook/bchain/coins/dcr"
"github.com/trezor/blockbook/bchain/coins/deeponion"
"github.com/trezor/blockbook/bchain/coins/digibyte"
"github.com/trezor/blockbook/bchain/coins/divi"
"github.com/trezor/blockbook/bchain/coins/dogecoin"
"github.com/trezor/blockbook/bchain/coins/eth"
"github.com/trezor/blockbook/bchain/coins/flo"
"github.com/trezor/blockbook/bchain/coins/fujicoin"
"github.com/trezor/blockbook/bchain/coins/gamecredits"
"github.com/trezor/blockbook/bchain/coins/grs"
"github.com/trezor/blockbook/bchain/coins/koto"
"github.com/trezor/blockbook/bchain/coins/liquid"
"github.com/trezor/blockbook/bchain/coins/litecoin"
"github.com/trezor/blockbook/bchain/coins/monacoin"
"github.com/trezor/blockbook/bchain/coins/monetaryunit"
"github.com/trezor/blockbook/bchain/coins/myriad"
"github.com/trezor/blockbook/bchain/coins/namecoin"
"github.com/trezor/blockbook/bchain/coins/nuls"
"github.com/trezor/blockbook/bchain/coins/omotenashicoin"
"github.com/trezor/blockbook/bchain/coins/pivx"
"github.com/trezor/blockbook/bchain/coins/polis"
"github.com/trezor/blockbook/bchain/coins/qtum"
"github.com/trezor/blockbook/bchain/coins/ravencoin"
"github.com/trezor/blockbook/bchain/coins/ritocoin"
"github.com/trezor/blockbook/bchain/coins/snowgem"
"github.com/trezor/blockbook/bchain/coins/unobtanium"
"github.com/trezor/blockbook/bchain/coins/vertcoin"
"github.com/trezor/blockbook/bchain/coins/viacoin"
"github.com/trezor/blockbook/bchain/coins/vipstarcoin"
"github.com/trezor/blockbook/bchain/coins/xzc"
"github.com/trezor/blockbook/bchain/coins/zec"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/bch"
"spacecruft.org/spacecruft/blockbook/bchain/coins/bellcoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/bitcore"
"spacecruft.org/spacecruft/blockbook/bchain/coins/bitzeny"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btg"
"spacecruft.org/spacecruft/blockbook/bchain/coins/cpuchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/dash"
"spacecruft.org/spacecruft/blockbook/bchain/coins/dcr"
"spacecruft.org/spacecruft/blockbook/bchain/coins/deeponion"
"spacecruft.org/spacecruft/blockbook/bchain/coins/digibyte"
"spacecruft.org/spacecruft/blockbook/bchain/coins/divi"
"spacecruft.org/spacecruft/blockbook/bchain/coins/dogecoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/eth"
"spacecruft.org/spacecruft/blockbook/bchain/coins/firo"
"spacecruft.org/spacecruft/blockbook/bchain/coins/flo"
"spacecruft.org/spacecruft/blockbook/bchain/coins/fujicoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/gamecredits"
"spacecruft.org/spacecruft/blockbook/bchain/coins/grs"
"spacecruft.org/spacecruft/blockbook/bchain/coins/koto"
"spacecruft.org/spacecruft/blockbook/bchain/coins/liquid"
"spacecruft.org/spacecruft/blockbook/bchain/coins/litecoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/monacoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/monetaryunit"
"spacecruft.org/spacecruft/blockbook/bchain/coins/myriad"
"spacecruft.org/spacecruft/blockbook/bchain/coins/namecoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/nuls"
"spacecruft.org/spacecruft/blockbook/bchain/coins/omotenashicoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/pivx"
"spacecruft.org/spacecruft/blockbook/bchain/coins/polis"
"spacecruft.org/spacecruft/blockbook/bchain/coins/qtum"
"spacecruft.org/spacecruft/blockbook/bchain/coins/ravencoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/ritocoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/snowgem"
"spacecruft.org/spacecruft/blockbook/bchain/coins/trezarcoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/unobtanium"
"spacecruft.org/spacecruft/blockbook/bchain/coins/vertcoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/viacoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/vipstarcoin"
"spacecruft.org/spacecruft/blockbook/bchain/coins/zec"
"spacecruft.org/spacecruft/blockbook/common"
)
type blockChainFactory func(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error)
@ -61,14 +62,17 @@ var BlockChainFactories = make(map[string]blockChainFactory)
func init() {
BlockChainFactories["Bitcoin"] = btc.NewBitcoinRPC
BlockChainFactories["Testnet"] = btc.NewBitcoinRPC
BlockChainFactories["Signet"] = btc.NewBitcoinRPC
BlockChainFactories["Zcash"] = zec.NewZCashRPC
BlockChainFactories["Zcash Testnet"] = zec.NewZCashRPC
BlockChainFactories["Ethereum"] = eth.NewEthereumRPC
BlockChainFactories["Ethereum Classic"] = eth.NewEthereumRPC
BlockChainFactories["Ethereum Testnet Ropsten"] = eth.NewEthereumRPC
BlockChainFactories["Ethereum Testnet Goerli"] = eth.NewEthereumRPC
BlockChainFactories["Bcash"] = bch.NewBCashRPC
BlockChainFactories["Bcash Testnet"] = bch.NewBCashRPC
BlockChainFactories["Bgold"] = btg.NewBGoldRPC
BlockChainFactories["Bgold Testnet"] = btg.NewBGoldRPC
BlockChainFactories["Dash"] = dash.NewDashRPC
BlockChainFactories["Dash Testnet"] = dash.NewDashRPC
BlockChainFactories["Decred"] = dcr.NewDecredRPC
@ -86,6 +90,7 @@ func init() {
BlockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC
BlockChainFactories["MonetaryUnit"] = monetaryunit.NewMonetaryUnitRPC
BlockChainFactories["DigiByte"] = digibyte.NewDigiByteRPC
BlockChainFactories["DigiByte Testnet"] = digibyte.NewDigiByteRPC
BlockChainFactories["Myriad"] = myriad.NewMyriadRPC
BlockChainFactories["Liquid"] = liquid.NewLiquidRPC
BlockChainFactories["Groestlcoin"] = grs.NewGroestlcoinRPC
@ -93,7 +98,7 @@ func init() {
BlockChainFactories["PIVX"] = pivx.NewPivXRPC
BlockChainFactories["PIVX Testnet"] = pivx.NewPivXRPC
BlockChainFactories["Polis"] = polis.NewPolisRPC
BlockChainFactories["Zcoin"] = xzc.NewZcoinRPC
BlockChainFactories["Firo"] = firo.NewFiroRPC
BlockChainFactories["Fujicoin"] = fujicoin.NewFujicoinRPC
BlockChainFactories["Flo"] = flo.NewFloRPC
BlockChainFactories["Bellcoin"] = bellcoin.NewBellcoinRPC
@ -114,6 +119,7 @@ func init() {
BlockChainFactories["Omotenashicoin"] = omotenashicoin.NewOmotenashiCoinRPC
BlockChainFactories["Omotenashicoin Testnet"] = omotenashicoin.NewOmotenashiCoinRPC
BlockChainFactories["BitZeny"] = bitzeny.NewBitZenyRPC
BlockChainFactories["Trezarcoin"] = trezarcoin.NewTrezarcoinRPC
}
// GetCoinNameFromConfig gets coin name and coin shortcut from config file
@ -185,8 +191,8 @@ func (c *blockChainWithMetrics) CreateMempool(chain bchain.BlockChain) (bchain.M
return c.b.CreateMempool(chain)
}
func (c *blockChainWithMetrics) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc) error {
return c.b.InitializeMempool(addrDescForOutpoint, onNewTxAddr)
func (c *blockChainWithMetrics) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc, onNewTx bchain.OnNewTxFunc) error {
return c.b.InitializeMempool(addrDescForOutpoint, onNewTxAddr, onNewTx)
}
func (c *blockChainWithMetrics) Shutdown(ctx context.Context) error {

View File

@ -15,9 +15,25 @@ import (
"github.com/martinboehm/btcutil/chaincfg"
"github.com/martinboehm/btcutil/hdkeychain"
"github.com/martinboehm/btcutil/txscript"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
)
// temp params for signet(wait btcd commit)
// magic numbers
const (
SignetMagic wire.BitcoinNet = 0x6a70c7f0
)
// chain parameters
var (
SigNetParams chaincfg.Params
)
func init() {
SigNetParams = chaincfg.TestNet3Params
SigNetParams.Net = SignetMagic
}
// OutputScriptToAddressesFunc converts ScriptPubKey to bitcoin addresses
type OutputScriptToAddressesFunc func(script []byte) ([]string, bool, error)
@ -63,6 +79,8 @@ func GetChainParams(chain string) *chaincfg.Params {
return &chaincfg.TestNet3Params
case "regtest":
return &chaincfg.RegressionNetParams
case "signet":
return &SigNetParams
}
return &chaincfg.MainNetParams
}

View File

@ -10,7 +10,7 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
)
func TestMain(m *testing.M) {
@ -259,10 +259,11 @@ func TestGetAddressesFromAddrDesc(t *testing.T) {
}
var (
testTx1, testTx2 bchain.Tx
testTx1, testTx2, testTx3 bchain.Tx
testTxPacked1 = "0001e2408ba8d7af5401000000017f9a22c9cbf54bd902400df746f138f37bcf5b4d93eb755820e974ba43ed5f42040000006a4730440220037f4ed5427cde81d55b9b6a2fd08c8a25090c2c2fff3a75c1a57625ca8a7118022076c702fe55969fa08137f71afd4851c48e31082dd3c40c919c92cdbc826758d30121029f6da5623c9f9b68a9baf9c1bc7511df88fa34c6c2f71f7c62f2f03ff48dca80feffffff019c9700000000000017a9146144d57c8aff48492c9dfb914e120b20bad72d6f8773d00700"
testTxPacked2 = "0007c91a899ab7da6a010000000001019d64f0c72a0d206001decbffaa722eb1044534c74eee7a5df8318e42a4323ec10000000017160014550da1f5d25a9dae2eafd6902b4194c4c6500af6ffffffff02809698000000000017a914cd668d781ece600efa4b2404dc91fd26b8b8aed8870553d7360000000017a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a8702473044022076aba4ad559616905fa51d4ddd357fc1fdb428d40cb388e042cdd1da4a1b7357022011916f90c712ead9a66d5f058252efd280439ad8956a967e95d437d246710bc9012102a80a5964c5612bb769ef73147b2cf3c149bc0fd4ecb02f8097629c94ab013ffd00000000"
testTxPacked3 = "00003d818bfda9aa3e02000000000102deb1999a857ab0a13d6b12fbd95ea75b409edde5f2ff747507ce42d9986a8b9d0000000000fdffffff9fd2d3361e203b2375eba6438efbef5b3075531e7e583c7cc76b7294fe7f22980000000000fdffffff02a0860100000000001600148091746745464e7555c31e9a5afceac14a02978ae7fc1c0000000000160014565ea9ff4589d3e05ba149ae6e257752bfdc2a1e0247304402207d67d320a8e813f986b35e9791935fcb736754812b7038686f5de6cfdcda99cd02201c3bb2c178e0056016437ecfe365a7eef84aa9d293ebdc566177af82e22fcdd3012103abb30c1bbe878b07b58dc169b1d061d48c60be8107f632a59778b38bf7ceea5a02473044022044f54a478cfe086e870cb026c9dcd4e14e63778bef569a4d55a6332725cd9a9802202f0e94c04e6f328fc64ad9efe552888c299750d1b8d033324825a3ff29920e030121036fcd433428aa7dc65c4f5408fa31f208c54fe4b4c6c1ae9c39a825ed4f1ac039813d0000"
)
func init() {
@ -335,6 +336,54 @@ func init() {
},
},
}
testTx3 = bchain.Tx{
Hex: "02000000000102deb1999a857ab0a13d6b12fbd95ea75b409edde5f2ff747507ce42d9986a8b9d0000000000fdffffff9fd2d3361e203b2375eba6438efbef5b3075531e7e583c7cc76b7294fe7f22980000000000fdffffff02a0860100000000001600148091746745464e7555c31e9a5afceac14a02978ae7fc1c0000000000160014565ea9ff4589d3e05ba149ae6e257752bfdc2a1e0247304402207d67d320a8e813f986b35e9791935fcb736754812b7038686f5de6cfdcda99cd02201c3bb2c178e0056016437ecfe365a7eef84aa9d293ebdc566177af82e22fcdd3012103abb30c1bbe878b07b58dc169b1d061d48c60be8107f632a59778b38bf7ceea5a02473044022044f54a478cfe086e870cb026c9dcd4e14e63778bef569a4d55a6332725cd9a9802202f0e94c04e6f328fc64ad9efe552888c299750d1b8d033324825a3ff29920e030121036fcd433428aa7dc65c4f5408fa31f208c54fe4b4c6c1ae9c39a825ed4f1ac039813d0000",
Blocktime: 1607805599,
Txid: "24551a58a1d1fb89d7052e2bbac7cb69a7825ee1e39439befbec8c32148cf735",
LockTime: 15745,
Version: 2,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: "",
},
Txid: "9d8b6a98d942ce077574fff2e5dd9e405ba75ed9fb126b3da1b07a859a99b1de",
Vout: 0,
Sequence: 4294967293,
},
{
ScriptSig: bchain.ScriptSig{
Hex: "",
},
Txid: "98227ffe94726bc77c3c587e1e5375305beffb8e43a6eb75233b201e36d3d29f",
Vout: 0,
Sequence: 4294967293,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(100000),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "00148091746745464e7555c31e9a5afceac14a02978a",
Addresses: []string{
"tb1qszghge69ge8824wrr6d94l82c99q99u2ccgv5w",
},
},
},
{
ValueSat: *big.NewInt(1899751),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "0014565ea9ff4589d3e05ba149ae6e257752bfdc2a1e",
Addresses: []string{
"tb1q2e02nl6938f7qkapfxhxufth22lac2s792vsxp",
},
},
},
},
}
}
func TestPackTx(t *testing.T) {
@ -372,6 +421,17 @@ func TestPackTx(t *testing.T) {
want: testTxPacked2,
wantErr: false,
},
{
name: "signet-1",
args: args{
tx: testTx3,
height: 15745,
blockTime: 1607805599,
parser: NewBitcoinParser(GetChainParams("signet"), &Configuration{}),
},
want: testTxPacked3,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -420,6 +480,16 @@ func TestUnpackTx(t *testing.T) {
want1: 510234,
wantErr: false,
},
{
name: "signet-1",
args: args{
packedTx: testTxPacked3,
parser: NewBitcoinParser(GetChainParams("signet"), &Configuration{}),
},
want: &testTx3,
want1: 15745,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -16,8 +16,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/martinboehm/btcd/wire"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/common"
)
// BitcoinRPC is an interface to JSON-RPC bitcoind service.
@ -155,12 +155,13 @@ func (b *BitcoinRPC) CreateMempool(chain bchain.BlockChain) (bchain.Mempool, err
}
// InitializeMempool creates ZeroMQ subscription and sets AddrDescForOutpointFunc to the Mempool
func (b *BitcoinRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc) error {
func (b *BitcoinRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc, onNewTx bchain.OnNewTxFunc) error {
if b.Mempool == nil {
return errors.New("Mempool not created")
}
b.Mempool.AddrDescForOutpoint = addrDescForOutpoint
b.Mempool.OnNewTxAddr = onNewTxAddr
b.Mempool.OnNewTx = onNewTx
if b.mq == nil {
mq, err := bchain.NewMQ(b.ChainConfig.MessageQueueBinding, b.pushHandler)
if err != nil {

View File

@ -12,7 +12,7 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
)
// https://whatthefee.io returns

View File

@ -8,9 +8,9 @@ import (
"github.com/martinboehm/btcd/chaincfg/chainhash"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
const (

View File

@ -12,7 +12,7 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// BGoldRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package cpuchain
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// CPUchainRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,8 +3,8 @@ package dash
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (

View File

@ -12,8 +12,8 @@ import (
"reflect"
"testing"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
type testBlock struct {

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const firstBlockWithSpecialTransactions = 1028160

View File

@ -9,17 +9,19 @@ import (
"math/big"
"strconv"
cfg "github.com/decred/dcrd/chaincfg"
"github.com/decred/dcrd/chaincfg/chainhash"
"github.com/decred/dcrd/hdkeychain"
"github.com/decred/dcrd/txscript"
cfg "github.com/decred/dcrd/chaincfg/v3"
"github.com/decred/dcrd/dcrec"
"github.com/decred/dcrd/dcrutil/v3"
"github.com/decred/dcrd/hdkeychain/v3"
"github.com/decred/dcrd/txscript/v3"
"github.com/juju/errors"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/base58"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
const (
@ -64,9 +66,9 @@ func NewDecredParser(params *chaincfg.Params, c *btc.Configuration) *DecredParse
switch d.BitcoinParser.Params.Name {
case "testnet3":
d.netConfig = &cfg.TestNet3Params
d.netConfig = cfg.TestNet3Params()
default:
d.netConfig = &cfg.MainNetParams
d.netConfig = cfg.MainNetParams()
}
return d
}
@ -202,7 +204,10 @@ func (p *DecredParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressD
return nil, err
}
scriptClass, addresses, _, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, script, p.netConfig)
const scriptVersion = 0
const treasuryEnabled = true
scriptClass, addresses, _, err := txscript.ExtractPkScriptAddrs(scriptVersion, script,
p.netConfig, treasuryEnabled)
if err != nil {
return nil, err
}
@ -240,7 +245,9 @@ func (p *DecredParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
}
func (p *DecredParser) addrDescFromExtKey(extKey *hdkeychain.ExtendedKey) (bchain.AddressDescriptor, error) {
var addr, err = extKey.Address(p.netConfig)
pk := extKey.SerializedPubKey()
hash := dcrutil.Hash160(pk)
addr, err := dcrutil.NewAddressPubKeyHash(hash, p.netConfig, dcrec.STEcdsaSecp256k1)
if err != nil {
return nil, err
}
@ -251,7 +258,7 @@ func (p *DecredParser) addrDescFromExtKey(extKey *hdkeychain.ExtendedKey) (bchai
// listed indexes
func (p *DecredParser) DeriveAddressDescriptors(xpub string, change uint32,
indexes []uint32) ([]bchain.AddressDescriptor, error) {
extKey, err := hdkeychain.NewKeyFromString(xpub)
extKey, err := hdkeychain.NewKeyFromString(xpub, p.netConfig)
if err != nil {
return nil, err
}
@ -282,7 +289,7 @@ func (p *DecredParser) DeriveAddressDescriptorsFromTo(xpub string, change uint32
if toIndex <= fromIndex {
return nil, errors.New("toIndex<=fromIndex")
}
extKey, err := hdkeychain.NewKeyFromString(xpub)
extKey, err := hdkeychain.NewKeyFromString(xpub, p.netConfig)
if err != nil {
return nil, err
}

View File

@ -9,8 +9,8 @@ import (
"reflect"
"testing"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
var (

View File

@ -15,12 +15,12 @@ import (
"sync"
"time"
"github.com/decred/dcrd/dcrjson"
"github.com/decred/dcrd/dcrjson/v3"
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/common"
)
// voteBitYes defines the vote bit set when a given block validates the previous

View File

@ -3,8 +3,8 @@ package deeponion
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// DeepOnionRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,17 +3,19 @@ package digibyte
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (
// MainnetMagic is mainnet network constant
MainnetMagic wire.BitcoinNet = 0xdab6c3fa
TestnetMagic wire.BitcoinNet = 0xddbdc8fd
)
var (
// MainNetParams are parser parameters for mainnet
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)
func init() {
@ -22,6 +24,12 @@ func init() {
MainNetParams.PubKeyHashAddrID = []byte{30}
MainNetParams.ScriptHashAddrID = []byte{63}
MainNetParams.Bech32HRPSegwit = "dgb"
TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{126}
TestNetParams.ScriptHashAddrID = []byte{140}
TestNetParams.Bech32HRPSegwit = "dgbt"
}
// DigiByteParser handle
@ -29,18 +37,27 @@ type DigiByteParser struct {
*btc.BitcoinParser
}
// NewDigiByteParser returns new VertcoinParser instance
// NewDigiByteParser returns new DigiByteParser instance
func NewDigiByteParser(params *chaincfg.Params, c *btc.Configuration) *DigiByteParser {
return &DigiByteParser{BitcoinParser: btc.NewBitcoinParser(params, c)}
}
// GetChainParams contains network parameters for the main DigiByte network
// and the DigiByte Testnet network
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err == nil {
err = chaincfg.Register(&TestNetParams)
}
if err != nil {
panic(err)
}
}
return &MainNetParams
switch chain {
case "test":
return &TestNetParams
default:
return &MainNetParams
}
}

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// DigiByteRPC is an interface to JSON-RPC bitcoind service.

View File

@ -10,9 +10,9 @@ import (
"github.com/juju/errors"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
const (

View File

@ -14,8 +14,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// DivicoinRPC is an interface to JSON-RPC bitcoind service.

View File

@ -5,9 +5,9 @@ import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
// magic numbers

View File

@ -14,8 +14,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// DogecoinRPC is an interface to JSON-RPC dogecoind service.

View File

@ -12,7 +12,7 @@ import (
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
)
var erc20abi = `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function","signature":"0x06fdde03"},
@ -183,18 +183,26 @@ func (b *EthereumRPC) EthereumTypeGetErc20ContractInfo(contractDesc bchain.Addre
address := EIP55Address(contractDesc)
data, err := b.ethCall(erc20NameSignature, address)
if err != nil {
return nil, err
// ignore the error from the eth_call - since geth v1.9.15 they changed the behavior
// and returning error "execution reverted" for some non contract addresses
// https://github.com/ethereum/go-ethereum/issues/21249#issuecomment-648647672
glog.Warning(errors.Annotatef(err, "erc20NameSignature %v", address))
return nil, nil
// return nil, errors.Annotatef(err, "erc20NameSignature %v", address)
}
name := parseErc20StringProperty(contractDesc, data)
if name != "" {
data, err = b.ethCall(erc20SymbolSignature, address)
if err != nil {
return nil, err
glog.Warning(errors.Annotatef(err, "erc20SymbolSignature %v", address))
return nil, nil
// return nil, errors.Annotatef(err, "erc20SymbolSignature %v", address)
}
symbol := parseErc20StringProperty(contractDesc, data)
data, err = b.ethCall(erc20DecimalsSignature, address)
if err != nil {
return nil, err
glog.Warning(errors.Annotatef(err, "erc20DecimalsSignature %v", address))
// return nil, errors.Annotatef(err, "erc20DecimalsSignature %v", address)
}
contract = &bchain.Erc20Contract{
Contract: address,

View File

@ -8,8 +8,8 @@ import (
"strings"
"testing"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/tests/dbtestdata"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/tests/dbtestdata"
)
func TestErc20_erc20GetTransfersFromLog(t *testing.T) {

View File

@ -8,7 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain"
"golang.org/x/crypto/sha3"
)
@ -311,8 +311,14 @@ func (p *EthereumParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) (
if pt.Receipt.GasUsed, err = hexDecodeBig(r.Receipt.GasUsed); err != nil {
return nil, errors.Annotatef(err, "GasUsed %v", r.Receipt.GasUsed)
}
if pt.Receipt.Status, err = hexDecodeBig(r.Receipt.Status); err != nil {
return nil, errors.Annotatef(err, "Status %v", r.Receipt.Status)
if r.Receipt.Status != "" {
if pt.Receipt.Status, err = hexDecodeBig(r.Receipt.Status); err != nil {
return nil, errors.Annotatef(err, "Status %v", r.Receipt.Status)
}
} else {
// unknown status, use 'U' as status bytes
// there is a potential for conflict with value 0x55 but this is not used by any chain at this moment
pt.Receipt.Status = []byte{'U'}
}
ptLogs := make([]*ProtoCompleteTransaction_ReceiptType_LogType, len(r.Receipt.Logs))
for i, l := range r.Receipt.Logs {
@ -379,9 +385,14 @@ func (p *EthereumParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
Topics: topics,
}
}
status := ""
// handle a special value []byte{'U'} as unknown state
if len(pt.Receipt.Status) != 1 || pt.Receipt.Status[0] != 'U' {
status = hexEncodeBig(pt.Receipt.Status)
}
rr = &rpcReceipt{
GasUsed: hexEncodeBig(pt.Receipt.GasUsed),
Status: hexEncodeBig(pt.Receipt.Status),
Status: status,
Logs: logs,
}
}
@ -461,16 +472,20 @@ func (p *EthereumParser) EthereumTypeGetErc20FromTx(tx *bchain.Tx) ([]bchain.Erc
return r, nil
}
// TxStatus is status of transaction
type TxStatus int
// statuses of transaction
const (
txStatusUnknown = iota - 2
txStatusPending
txStatusFailure
txStatusOK
TxStatusUnknown = TxStatus(iota - 2)
TxStatusPending
TxStatusFailure
TxStatusOK
)
// EthereumTxData contains ethereum specific transaction data
type EthereumTxData struct {
Status int `json:"status"` // 1 OK, 0 Fail, -1 pending, -2 unknown
Status TxStatus `json:"status"` // 1 OK, 0 Fail, -1 pending, -2 unknown
Nonce uint64 `json:"nonce"`
GasLimit *big.Int `json:"gaslimit"`
GasUsed *big.Int `json:"gasused"`
@ -480,8 +495,13 @@ type EthereumTxData struct {
// GetEthereumTxData returns EthereumTxData from bchain.Tx
func GetEthereumTxData(tx *bchain.Tx) *EthereumTxData {
etd := EthereumTxData{Status: txStatusPending}
csd, ok := tx.CoinSpecificData.(completeTransaction)
return GetEthereumTxDataFromSpecificData(tx.CoinSpecificData)
}
// GetEthereumTxDataFromSpecificData returns EthereumTxData from coinSpecificData
func GetEthereumTxDataFromSpecificData(coinSpecificData interface{}) *EthereumTxData {
etd := EthereumTxData{Status: TxStatusPending}
csd, ok := coinSpecificData.(completeTransaction)
if ok {
if csd.Tx != nil {
etd.Nonce, _ = hexutil.DecodeUint64(csd.Tx.AccountNonce)
@ -492,11 +512,11 @@ func GetEthereumTxData(tx *bchain.Tx) *EthereumTxData {
if csd.Receipt != nil {
switch csd.Receipt.Status {
case "0x1":
etd.Status = txStatusOK
etd.Status = TxStatusOK
case "": // old transactions did not set status
etd.Status = txStatusUnknown
etd.Status = TxStatusUnknown
default:
etd.Status = txStatusFailure
etd.Status = TxStatusFailure
}
etd.GasUsed, _ = hexutil.DecodeBig(csd.Receipt.GasUsed)
}

View File

@ -9,8 +9,8 @@ import (
"reflect"
"testing"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/tests/dbtestdata"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/tests/dbtestdata"
)
func TestEthParser_GetAddrDescFromAddress(t *testing.T) {
@ -68,7 +68,7 @@ func TestEthParser_GetAddrDescFromAddress(t *testing.T) {
}
}
var testTx1, testTx2 bchain.Tx
var testTx1, testTx2, testTx1Failed, testTx1NoStatus bchain.Tx
func init() {
@ -156,6 +156,83 @@ func init() {
},
},
}
testTx1Failed = bchain.Tx{
Blocktime: 1534858022,
Time: 1534858022,
Txid: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
Vin: []bchain.Vin{
{
Addresses: []string{"0x3E3a3D69dc66bA10737F531ed088954a9EC89d97"},
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(1999622000000000000),
ScriptPubKey: bchain.ScriptPubKey{
Addresses: []string{"0x555Ee11FBDDc0E49A9bAB358A8941AD95fFDB48f"},
},
},
},
CoinSpecificData: completeTransaction{
Tx: &rpcTransaction{
AccountNonce: "0xb26c",
GasPrice: "0x430e23400",
GasLimit: "0x5208",
To: "0x555Ee11FBDDc0E49A9bAB358A8941AD95fFDB48f",
Value: "0x1bc0159d530e6000",
Payload: "0x",
Hash: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
BlockNumber: "0x41eee8",
From: "0x3E3a3D69dc66bA10737F531ed088954a9EC89d97",
TransactionIndex: "0xa",
},
Receipt: &rpcReceipt{
GasUsed: "0x5208",
Status: "0x0",
Logs: []*rpcLog{},
},
},
}
testTx1NoStatus = bchain.Tx{
Blocktime: 1534858022,
Time: 1534858022,
Txid: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
Vin: []bchain.Vin{
{
Addresses: []string{"0x3E3a3D69dc66bA10737F531ed088954a9EC89d97"},
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(1999622000000000000),
ScriptPubKey: bchain.ScriptPubKey{
Addresses: []string{"0x555Ee11FBDDc0E49A9bAB358A8941AD95fFDB48f"},
},
},
},
CoinSpecificData: completeTransaction{
Tx: &rpcTransaction{
AccountNonce: "0xb26c",
GasPrice: "0x430e23400",
GasLimit: "0x5208",
To: "0x555Ee11FBDDc0E49A9bAB358A8941AD95fFDB48f",
Value: "0x1bc0159d530e6000",
Payload: "0x",
Hash: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
BlockNumber: "0x41eee8",
From: "0x3E3a3D69dc66bA10737F531ed088954a9EC89d97",
TransactionIndex: "0xa",
},
Receipt: &rpcReceipt{
GasUsed: "0x5208",
Status: "",
Logs: []*rpcLog{},
},
},
}
}
func TestEthereumParser_PackTx(t *testing.T) {
@ -189,6 +266,24 @@ func TestEthereumParser_PackTx(t *testing.T) {
},
want: dbtestdata.EthTx2Packed,
},
{
name: "3",
args: args{
tx: &testTx1Failed,
height: 4321000,
blockTime: 1534858022,
},
want: dbtestdata.EthTx1FailedPacked,
},
{
name: "4",
args: args{
tx: &testTx1NoStatus,
height: 4321000,
blockTime: 1534858022,
},
want: dbtestdata.EthTx1NoStatusPacked,
},
}
p := NewEthereumParser(1)
for _, tt := range tests {
@ -230,6 +325,18 @@ func TestEthereumParser_UnpackTx(t *testing.T) {
want: &testTx2,
want1: 4321000,
},
{
name: "3",
args: args{hex: dbtestdata.EthTx1FailedPacked},
want: &testTx1Failed,
want1: 4321000,
},
{
name: "4",
args: args{hex: dbtestdata.EthTx1NoStatusPacked},
want: &testTx1NoStatus,
want1: 4321000,
},
}
p := NewEthereumParser(1)
for _, tt := range tests {

View File

@ -11,13 +11,14 @@ import (
ethereum "github.com/ethereum/go-ethereum"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/common"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/common"
)
// EthereumNet type specifies the type of ethereum network
@ -28,6 +29,8 @@ const (
MainNet EthereumNet = 1
// TestNet is Ropsten test network
TestNet EthereumNet = 3
// TestNetGoerli is Goerli test network
TestNetGoerli EthereumNet = 5
)
// Configuration represents json config file
@ -159,6 +162,9 @@ func (b *EthereumRPC) Initialize() error {
b.Testnet = true
b.Network = "testnet"
break
case TestNetGoerli:
b.Testnet = true
b.Network = "goerli"
default:
return errors.Errorf("Unknown network id %v", id)
}
@ -177,7 +183,7 @@ func (b *EthereumRPC) CreateMempool(chain bchain.BlockChain) (bchain.Mempool, er
}
// InitializeMempool creates subscriptions to newHeads and newPendingTransactions
func (b *EthereumRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc) error {
func (b *EthereumRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOutpointFunc, onNewTxAddr bchain.OnNewTxAddrFunc, onNewTx bchain.OnNewTxFunc) error {
if b.Mempool == nil {
return errors.New("Mempool not created")
}
@ -192,6 +198,7 @@ func (b *EthereumRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOu
}
b.Mempool.OnNewTxAddr = onNewTxAddr
b.Mempool.OnNewTx = onNewTx
if err = b.subscribeEvents(); err != nil {
return err
@ -333,19 +340,15 @@ func (b *EthereumRPC) GetChainInfo() (*bchain.ChainInfo, error) {
if err != nil {
return nil, err
}
var ver, protocol string
var ver string
if err := b.rpc.CallContext(ctx, &ver, "web3_clientVersion"); err != nil {
return nil, err
}
if err := b.rpc.CallContext(ctx, &protocol, "eth_protocolVersion"); err != nil {
return nil, err
}
rv := &bchain.ChainInfo{
Blocks: int(h.Number.Int64()),
Bestblockhash: h.Hash().Hex(),
Difficulty: h.Difficulty.String(),
Version: ver,
ProtocolVersion: protocol,
Blocks: int(h.Number.Int64()),
Bestblockhash: h.Hash().Hex(),
Difficulty: h.Difficulty.String(),
Version: ver,
}
idi := int(id.Uint64())
if idi == 1 {
@ -721,6 +724,18 @@ func (b *EthereumRPC) EthereumTypeEstimateGas(params map[string]interface{}) (ui
if ok && len(s) > 0 {
msg.Data = ethcommon.FromHex(s)
}
s, ok = getStringFromMap("value", params)
if ok && len(s) > 0 {
msg.Value, _ = hexutil.DecodeBig(s)
}
s, ok = getStringFromMap("gas", params)
if ok && len(s) > 0 {
msg.Gas, _ = hexutil.DecodeUint64(s)
}
s, ok = getStringFromMap("gasPrice", params)
if ok && len(s) > 0 {
msg.GasPrice, _ = hexutil.DecodeBig(s)
}
return b.client.EstimateGas(ctx, msg)
}

View File

@ -1,11 +1,11 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: tx.proto
// source: bchain/coins/eth/ethtx.proto
/*
Package eth is a generated protocol buffer package.
It is generated from these files:
tx.proto
bchain/coins/eth/ethtx.proto
It has these top-level messages:
ProtoCompleteTransaction
@ -228,33 +228,34 @@ func init() {
proto.RegisterType((*ProtoCompleteTransaction_ReceiptType_LogType)(nil), "eth.ProtoCompleteTransaction.ReceiptType.LogType")
}
func init() { proto.RegisterFile("tx.proto", fileDescriptor0) }
func init() { proto.RegisterFile("bchain/coins/eth/ethtx.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 393 bytes of a gzipped FileDescriptorProto
// 409 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xdf, 0x8a, 0xd4, 0x30,
0x14, 0xc6, 0xe9, 0x9f, 0xf9, 0xb3, 0xa7, 0x55, 0x24, 0x88, 0x84, 0xe2, 0x45, 0x59, 0xbc, 0xa8,
0x5e, 0x14, 0x5c, 0x7d, 0x81, 0x75, 0xc4, 0x55, 0x18, 0xd6, 0x21, 0x46, 0xef, 0xb3, 0x69, 0xd8,
0x29, 0xb6, 0x4d, 0x69, 0x52, 0xe8, 0xbe, 0x91, 0x2f, 0xe4, 0xbb, 0x78, 0x29, 0x39, 0x4d, 0xd7,
0x11, 0x51, 0xbc, 0x3b, 0xbf, 0x6f, 0xce, 0x37, 0xf9, 0xbe, 0xa4, 0xb0, 0xb5, 0x53, 0xd9, 0x0f,
0xda, 0x6a, 0x12, 0x29, 0x7b, 0x3c, 0xff, 0xb6, 0x02, 0x7a, 0x70, 0xb8, 0xd3, 0x6d, 0xdf, 0x28,
0xab, 0xf8, 0x20, 0x3a, 0x23, 0xa4, 0xad, 0x75, 0x47, 0x72, 0x48, 0xde, 0x34, 0x5a, 0x7e, 0xbd,
0x1e, 0xdb, 0x1b, 0x35, 0xd0, 0x20, 0x0f, 0x8a, 0x07, 0xec, 0x54, 0x22, 0x4f, 0xe1, 0x0c, 0x91,
0xd7, 0xad, 0xa2, 0x61, 0x1e, 0x14, 0x31, 0xfb, 0x25, 0x90, 0xd7, 0x10, 0xf2, 0x89, 0x46, 0x79,
0x50, 0x24, 0x17, 0xcf, 0x4a, 0x65, 0x8f, 0xe5, 0xdf, 0x8e, 0x2a, 0xf9, 0xc4, 0xef, 0x7a, 0xc5,
0x42, 0x3e, 0x91, 0x1d, 0x6c, 0x98, 0x92, 0xaa, 0xee, 0x2d, 0x8d, 0xd1, 0xfa, 0xfc, 0xdf, 0x56,
0xbf, 0x8c, 0xfe, 0xc5, 0x99, 0xfd, 0x08, 0x60, 0x3d, 0xff, 0x27, 0x39, 0x87, 0xf4, 0x52, 0x4a,
0x3d, 0x76, 0xf6, 0x5a, 0x77, 0x52, 0x61, 0x8d, 0x98, 0xfd, 0xa6, 0x91, 0x0c, 0xb6, 0x57, 0xc2,
0x1c, 0x86, 0x5a, 0xce, 0x35, 0x52, 0x76, 0xcf, 0xfe, 0xb7, 0x7d, 0xdd, 0xd6, 0x16, 0xbb, 0xc4,
0xec, 0x9e, 0xc9, 0x63, 0x58, 0x7d, 0x11, 0xcd, 0xa8, 0x30, 0x69, 0xca, 0x66, 0x20, 0x14, 0x36,
0x07, 0x71, 0xd7, 0x68, 0x51, 0xd1, 0x15, 0xea, 0x0b, 0x12, 0x02, 0xf1, 0x7b, 0x61, 0x8e, 0x74,
0x8d, 0x32, 0xce, 0xe4, 0x21, 0x84, 0x5c, 0xd3, 0x0d, 0x2a, 0x21, 0xd7, 0x6e, 0xe7, 0xdd, 0xa0,
0x5b, 0xba, 0x9d, 0x77, 0xdc, 0x4c, 0x5e, 0xc0, 0xa3, 0x93, 0xca, 0x1f, 0xba, 0x4a, 0x4d, 0xf4,
0x0c, 0x9f, 0xe3, 0x0f, 0x3d, 0xfb, 0x1e, 0x40, 0x72, 0x72, 0x27, 0x2e, 0xcd, 0x95, 0x30, 0x9f,
0x8d, 0xaa, 0xb0, 0x7a, 0xca, 0x16, 0x24, 0x4f, 0x60, 0xfd, 0xc9, 0x0a, 0x3b, 0x1a, 0xdf, 0xd9,
0x13, 0xd9, 0x41, 0xb4, 0xd7, 0xb7, 0x34, 0xca, 0xa3, 0x22, 0xb9, 0x78, 0xf9, 0xdf, 0xb7, 0x5f,
0xee, 0xf5, 0x2d, 0xbe, 0x82, 0x73, 0x67, 0x1f, 0x61, 0xe3, 0xd9, 0x25, 0xb8, 0xac, 0xaa, 0x41,
0x19, 0xb3, 0x24, 0xf0, 0xe8, 0xba, 0xbe, 0x15, 0x56, 0xf8, 0xf3, 0x71, 0x76, 0xa9, 0xb8, 0xee,
0x6b, 0x69, 0x30, 0x40, 0xca, 0x3c, 0xdd, 0xac, 0xf1, 0xb3, 0x7d, 0xf5, 0x33, 0x00, 0x00, 0xff,
0xff, 0xde, 0xd5, 0x28, 0xa3, 0xc2, 0x02, 0x00, 0x00,
0x18, 0xc5, 0xe9, 0x9f, 0x99, 0xd9, 0xfd, 0xa6, 0x8a, 0x04, 0x91, 0x30, 0xec, 0x45, 0x59, 0xbc,
0x18, 0xbd, 0xe8, 0xe2, 0xea, 0x0b, 0xac, 0x23, 0xae, 0xc2, 0xb0, 0x0e, 0x31, 0x7a, 0x9f, 0x49,
0xc3, 0x36, 0x38, 0x6d, 0x4a, 0x93, 0x42, 0xf7, 0x8d, 0x7c, 0x21, 0xdf, 0xc5, 0x4b, 0xc9, 0xd7,
0x74, 0x1d, 0x11, 0x65, 0x2f, 0x0a, 0xf9, 0x9d, 0x7e, 0xa7, 0x39, 0x27, 0x29, 0x9c, 0xed, 0x65,
0x25, 0x74, 0x73, 0x21, 0x8d, 0x6e, 0xec, 0x85, 0x72, 0x95, 0x7f, 0xdc, 0x50, 0xb4, 0x9d, 0x71,
0x86, 0x24, 0xca, 0x55, 0xe7, 0xdf, 0x67, 0x40, 0x77, 0x1e, 0x37, 0xa6, 0x6e, 0x0f, 0xca, 0x29,
0xde, 0x89, 0xc6, 0x0a, 0xe9, 0xb4, 0x69, 0x48, 0x0e, 0xcb, 0xb7, 0x07, 0x23, 0xbf, 0xdd, 0xf4,
0xf5, 0x5e, 0x75, 0x34, 0xca, 0xa3, 0xf5, 0x23, 0x76, 0x2c, 0x91, 0x33, 0x38, 0x45, 0xe4, 0xba,
0x56, 0x34, 0xce, 0xa3, 0x75, 0xca, 0x7e, 0x0b, 0xe4, 0x0d, 0xc4, 0x7c, 0xa0, 0x49, 0x1e, 0xad,
0x97, 0x97, 0xcf, 0x0b, 0xe5, 0xaa, 0xe2, 0x5f, 0x5b, 0x15, 0x7c, 0xe0, 0x77, 0xad, 0x62, 0x31,
0x1f, 0xc8, 0x06, 0x16, 0x4c, 0x49, 0xa5, 0x5b, 0x47, 0x53, 0xb4, 0xbe, 0xf8, 0xbf, 0x35, 0x0c,
0xa3, 0x7f, 0x72, 0xae, 0x7e, 0x46, 0x30, 0x1f, 0xbf, 0x49, 0xce, 0x21, 0xbb, 0x92, 0xd2, 0xf4,
0x8d, 0xbb, 0x31, 0x8d, 0x54, 0x58, 0x23, 0x65, 0x7f, 0x68, 0x64, 0x05, 0x27, 0xd7, 0xc2, 0xee,
0x3a, 0x2d, 0xc7, 0x1a, 0x19, 0xbb, 0xe7, 0xf0, 0x6e, 0xab, 0x6b, 0xed, 0xb0, 0x4b, 0xca, 0xee,
0x99, 0x3c, 0x85, 0xd9, 0x57, 0x71, 0xe8, 0x15, 0x26, 0xcd, 0xd8, 0x08, 0x84, 0xc2, 0x62, 0x27,
0xee, 0x0e, 0x46, 0x94, 0x74, 0x86, 0xfa, 0x84, 0x84, 0x40, 0xfa, 0x41, 0xd8, 0x8a, 0xce, 0x51,
0xc6, 0x35, 0x79, 0x0c, 0x31, 0x37, 0x74, 0x81, 0x4a, 0xcc, 0x8d, 0x9f, 0x79, 0xdf, 0x99, 0x9a,
0x9e, 0x8c, 0x33, 0x7e, 0x4d, 0x5e, 0xc2, 0x93, 0xa3, 0xca, 0x1f, 0x9b, 0x52, 0x0d, 0xf4, 0x14,
0xaf, 0xe3, 0x2f, 0x7d, 0xf5, 0x23, 0x82, 0xe5, 0xd1, 0x99, 0xf8, 0x34, 0xd7, 0xc2, 0x7e, 0xb1,
0xaa, 0xc4, 0xea, 0x19, 0x9b, 0x90, 0x3c, 0x83, 0xf9, 0x67, 0x27, 0x5c, 0x6f, 0x43, 0xe7, 0x40,
0x64, 0x03, 0xc9, 0xd6, 0xdc, 0xd2, 0x24, 0x4f, 0xd6, 0xcb, 0xcb, 0x57, 0x0f, 0x3e, 0xfd, 0x62,
0x6b, 0x6e, 0xf1, 0x16, 0xbc, 0x7b, 0xf5, 0x09, 0x16, 0x81, 0x7d, 0x82, 0xab, 0xb2, 0xec, 0x94,
0xb5, 0x53, 0x82, 0x80, 0xbe, 0xeb, 0x3b, 0xe1, 0x44, 0xd8, 0x1f, 0xd7, 0x3e, 0x15, 0x37, 0xad,
0x96, 0x16, 0x03, 0x64, 0x2c, 0xd0, 0x7e, 0x8e, 0xbf, 0xed, 0xeb, 0x5f, 0x01, 0x00, 0x00, 0xff,
0xff, 0xc2, 0x69, 0x8d, 0xdf, 0xd6, 0x02, 0x00, 0x00,
}

View File

@ -0,0 +1,64 @@
package firo
import (
"bytes"
"io"
"github.com/martinboehm/btcd/chaincfg/chainhash"
"github.com/martinboehm/btcd/wire"
)
// FiroMsgTx encapsulate firo tx and extra
type FiroMsgTx struct {
wire.MsgTx
Extra []byte
}
// TxHash calculate hash of transaction
func (msg *FiroMsgTx) TxHash() chainhash.Hash {
extraSize := uint64(len(msg.Extra))
sizeOfExtraSize := 0
if extraSize != 0 {
sizeOfExtraSize = wire.VarIntSerializeSize(extraSize)
}
// Original payload
buf := bytes.NewBuffer(make([]byte, 0,
msg.SerializeSizeStripped()+sizeOfExtraSize+len(msg.Extra)))
_ = msg.SerializeNoWitness(buf)
// Extra payload
if extraSize != 0 {
wire.WriteVarInt(buf, 0, extraSize)
buf.Write(msg.Extra)
}
return chainhash.DoubleHashH(buf.Bytes())
}
// FiroDecode to decode bitcoin tx and extra
func (msg *FiroMsgTx) FiroDecode(r io.Reader, pver uint32, enc wire.MessageEncoding) error {
if err := msg.MsgTx.BtcDecode(r, pver, enc); err != nil {
return err
}
// extra
version := uint32(msg.Version)
txVersion := version & 0xffff
txType := (version >> 16) & 0xffff
if txVersion == 3 && txType != 0 {
extraSize, err := wire.ReadVarInt(r, 0)
if err != nil {
return err
}
msg.Extra = make([]byte, extraSize)
_, err = io.ReadFull(r, msg.Extra[:])
if err != nil {
return err
}
}
return nil
}

View File

@ -1,4 +1,4 @@
package xzc
package firo
import (
"bytes"
@ -9,15 +9,18 @@ import (
"github.com/martinboehm/btcd/chaincfg/chainhash"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (
OpZeroCoinMint = 0xc1
OpZeroCoinSpend = 0xc2
OpSigmaMint = 0xc3
OpSigmaSpend = 0xc4
OpZeroCoinMint = 0xc1
OpZeroCoinSpend = 0xc2
OpSigmaMint = 0xc3
OpSigmaSpend = 0xc4
OpLelantusMint = 0xc5
OpLelantusJMint = 0xc6
OpLelantusJoinSplit = 0xc7
MainnetMagic wire.BitcoinNet = 0xe3d9fef1
TestnetMagic wire.BitcoinNet = 0xcffcbeea
@ -28,6 +31,8 @@ const (
MTPL = 64
SpendTxID = "0000000000000000000000000000000000000000000000000000000000000000"
TransactionQuorumCommitmentType = 6
)
var (
@ -58,21 +63,21 @@ func init() {
RegtestParams.Net = RegtestMagic
}
// ZcoinParser handle
type ZcoinParser struct {
// FiroParser handle
type FiroParser struct {
*btc.BitcoinParser
}
// NewZcoinParser returns new ZcoinParser instance
func NewZcoinParser(params *chaincfg.Params, c *btc.Configuration) *ZcoinParser {
return &ZcoinParser{
// NewFiroParser returns new FiroParser instance
func NewFiroParser(params *chaincfg.Params, c *btc.Configuration) *FiroParser {
return &FiroParser{
BitcoinParser: btc.NewBitcoinParser(params, c),
}
}
// GetChainParams contains network parameters for the main Zcoin network,
// the regression test Zcoin network, the test Zcoin network and
// the simulation test Zcoin network, in this order
// GetChainParams contains network parameters for the main Firo network,
// the regression test Firo network, the test Firo network and
// the simulation test Firo network, in this order
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
@ -97,7 +102,7 @@ func GetChainParams(chain string) *chaincfg.Params {
}
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
func (p *ZcoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
func (p *FiroParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
if len(addrDesc) > 0 {
switch addrDesc[0] {
@ -109,6 +114,12 @@ func (p *ZcoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor
return []string{"Sigmamint"}, false, nil
case OpSigmaSpend:
return []string{"Sigmaspend"}, false, nil
case OpLelantusMint:
return []string{"LelantusMint"}, false, nil
case OpLelantusJMint:
return []string{"LelantusJMint"}, false, nil
case OpLelantusJoinSplit:
return []string{"LelantusJoinSplit"}, false, nil
}
}
@ -116,17 +127,27 @@ func (p *ZcoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor
}
// PackTx packs transaction to byte array using protobuf
func (p *ZcoinParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
func (p *FiroParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
return p.BaseParser.PackTx(tx, height, blockTime)
}
// UnpackTx unpacks transaction from protobuf byte array
func (p *ZcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
func (p *FiroParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
return p.BaseParser.UnpackTx(buf)
}
// TxFromFiroMsgTx converts bitcoin wire Tx to bchain.Tx
func (p *FiroParser) TxFromFiroMsgTx(t *FiroMsgTx, parseAddresses bool) bchain.Tx {
btx := p.TxFromMsgTx(&t.MsgTx, parseAddresses)
// NOTE: wire.MsgTx.TxHash() doesn't include extra
btx.Txid = t.TxHash().String()
return btx
}
// ParseBlock parses raw block to our Block struct
func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
func (p *FiroParser) ParseBlock(b []byte) (*bchain.Block, error) {
reader := bytes.NewReader(b)
// parse standard block header first
@ -181,16 +202,37 @@ func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
txs := make([]bchain.Tx, ntx)
for i := uint64(0); i < ntx; i++ {
tx := wire.MsgTx{}
tx := FiroMsgTx{}
err := tx.BtcDecode(reader, 0, wire.WitnessEncoding)
if err != nil {
// read version and seek back
var version uint32 = 0
if err = binary.Read(reader, binary.LittleEndian, &version); err != nil {
return nil, err
}
btx := p.TxFromMsgTx(&tx, false)
if _, err = reader.Seek(-4, io.SeekCurrent); err != nil {
return nil, err
}
p.parseZcoinTx(&btx)
txVersion := version & 0xffff
txType := (version >> 16) & 0xffff
enc := wire.WitnessEncoding
// transaction quorum commitment could not be parsed with witness flag
if txVersion == 3 && txType == TransactionQuorumCommitmentType {
enc = wire.BaseEncoding
}
if err = tx.FiroDecode(reader, 0, enc); err != nil {
return nil, err
}
btx := p.TxFromFiroMsgTx(&tx, false)
if err = p.parseFiroTx(&btx); err != nil {
return nil, err
}
txs[i] = btx
}
@ -205,7 +247,7 @@ func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
}
// ParseTxFromJson parses JSON message containing transaction and returns Tx struct
func (p *ZcoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
func (p *FiroParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
var tx bchain.Tx
err := json.Unmarshal(msg, &tx)
if err != nil {
@ -222,12 +264,12 @@ func (p *ZcoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
vout.JsonValue = ""
}
p.parseZcoinTx(&tx)
p.parseFiroTx(&tx)
return &tx, nil
}
func (p *ZcoinParser) parseZcoinTx(tx *bchain.Tx) error {
func (p *FiroParser) parseFiroTx(tx *bchain.Tx) error {
for i := range tx.Vin {
vin := &tx.Vin[i]

View File

@ -1,6 +1,6 @@
// +build unittest
package xzc
package firo
import (
"bytes"
@ -13,16 +13,18 @@ import (
"strings"
"testing"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
var (
testTx1, testTx2, testTx3, testTx4 bchain.Tx
testTxPacked1, testTxPacked2, testTxPacked3, testTxPacked4 string
rawBlock1, rawBlock2 string
jsonTx json.RawMessage
testTx1, testTx2, testTx3, testTx4, testTx5, testTx6 bchain.Tx
rawTestTx1, rawTestTx2, rawTestTx3, rawTestTx4, rawTestTx5, rawTestTx6 string
testTxPacked1, testTxPacked2, testTxPacked3, testTxPacked4, testTxPacked5, testTxPacked6 string
rawBlock1, rawBlock2, rawBlock3 string
jsonTx json.RawMessage
)
func readHexs(path string) []string {
@ -39,12 +41,15 @@ func init() {
rawBlocks := readHexs("./testdata/rawblock.hex")
rawBlock1 = rawBlocks[0]
rawBlock2 = rawBlocks[1]
rawBlock3 = rawBlocks[2]
hextxs := readHexs("./testdata/txs.hex")
rawTestTx1 := hextxs[0]
rawTestTx2 := hextxs[1]
rawTestTx3 := hextxs[2]
rawTestTx4 := hextxs[3]
rawTestTx1 = hextxs[0]
rawTestTx2 = hextxs[1]
rawTestTx3 = hextxs[2]
rawTestTx4 = hextxs[3]
rawTestTx5 = hextxs[4]
rawTestTx6 = hextxs[5]
rawSpendHex := readHexs("./testdata/rawspend.hex")[0]
@ -59,13 +64,15 @@ func init() {
testTxPacked2 = testTxPackeds[1]
testTxPacked3 = testTxPackeds[2]
testTxPacked4 = testTxPackeds[3]
testTxPacked5 = testTxPackeds[4]
testTxPacked6 = testTxPackeds[5]
testTx1 = bchain.Tx{
Hex: rawTestTx1,
Blocktime: 1533980594,
Time: 1533980594,
Txid: "9d9e759dd970d86df9e105a7d4f671543bc16a03b6c5d2b48895f2a00aa7dd23",
LockTime: 0,
LockTime: 99688,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
@ -78,14 +85,14 @@ func init() {
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(18188266638),
ValueSat: *big.NewInt(100000000),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "c10280004c80f767f3ee79953c67a7ed386dcccf1243619eb4bbbe414a3982dd94a83c1b69ac52d6ab3b653a3e05c4e4516c8dfe1e58ada40461bc5835a4a0d0387a51c29ac11b72ae25bbcdef745f50ad08f08b3e9bc2c31a35444398a490e65ac090e9f341f1abdebe47e57e8237ac25d098e951b4164a35caea29f30acb50b12e4425df28",
},
},
{
ValueSat: *big.NewInt(18188266638),
ValueSat: *big.NewInt(871824000),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914c963f917c7f23cb4243e079db33107571b87690588ac",
@ -105,9 +112,7 @@ func init() {
LockTime: 0,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: rawSpendHex,
},
Coinbase: rawSpendHex,
Txid: "0000000000000000000000000000000000000000000000000000000000000000",
Vout: 4294967295,
Sequence: 2,
@ -226,7 +231,7 @@ func init() {
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914ff71b0c9c2a90c6164a50a2fb523eb54a8a6b55088ac",
Addresses: []string{
"a1HwTdCmQV3NspP2QqCGpehoFpi8NY4Zg3",
"aQ18FBVFtnueucZKeVg4srhmzbpAeb1KoN",
},
},
},
@ -250,6 +255,103 @@ func init() {
},
},
},
// TODO: test segwit
},
}
testTx5 = bchain.Tx{
Hex: rawTestTx5,
Blocktime: 1591752749,
Time: 1591752749,
Txid: "8d1f32f35c32d2c127a7400dc1ec52049fbf0b8bcdf284cfaa3da59b6169a22d",
LockTime: 0,
Vin: []bchain.Vin{},
Vout: []bchain.Vout{},
}
testTx6 = bchain.Tx{
Hex: rawTestTx6,
Blocktime: 1591762049,
Time: 1591762049,
Txid: "e5767d3606230a65f150837a6f28b4f0e4c2702a683045df3883d57702739c61",
LockTime: 0,
Vin: []bchain.Vin{
{
Coinbase: "02b4140101",
Sequence: 4294967295,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(1400000000),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "2103fb09a216761d5e7f248294970c2370f7f84ce1ad564b8e7096b1e19116af1d52ac",
Addresses: []string{
"TAn9Ghkp31myXRgejCj11wWVHT14Lsj349",
},
},
},
{
ValueSat: *big.NewInt(50000000),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914296134d2415bf1f2b518b3f673816d7e603b160088ac",
Addresses: []string{
"TDk19wPKYq91i18qmY6U9FeTdTxwPeSveo",
},
},
},
{
ValueSat: *big.NewInt(50000000),
N: 2,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914e1e1dc06a889c1b6d3eb00eef7a96f6a7cfb884888ac",
Addresses: []string{
"TWZZcDGkNixTAMtRBqzZkkMHbq1G6vUTk5",
},
},
},
{
ValueSat: *big.NewInt(50000000),
N: 3,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914ab03ecfddee6330497be894d16c29ae341c123aa88ac",
Addresses: []string{
"TRZTFdNCKCKbLMQV8cZDkQN9Vwuuq4gDzT",
},
},
},
{
ValueSat: *big.NewInt(150000000),
N: 4,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9144281a58a1d5b2d3285e00cb45a8492debbdad4c588ac",
Addresses: []string{
"TG2ruj59E5b1u9G3F7HQVs6pCcVDBxrQve",
},
},
},
{
ValueSat: *big.NewInt(50000000),
N: 5,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9141fd264c0bb53bd9fef18e2248ddf1383d6e811ae88ac",
Addresses: []string{
"TCsTzQZKVn4fao8jDmB9zQBk9YQNEZ3XfS",
},
},
},
{
ValueSat: *big.NewInt(750000000),
N: 6,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a91471a3892d164ffa3829078bf9ad5f114a3908ce5588ac",
Addresses: []string{
"TLL5GQULX4uBfz7yXL6VcZyvzdKVv1RGxm",
},
},
},
},
}
}
@ -263,32 +365,32 @@ func TestMain(m *testing.M) {
func TestGetAddrDesc(t *testing.T) {
type args struct {
tx bchain.Tx
parser *ZcoinParser
parser *FiroParser
}
tests := []struct {
name string
args args
}{
{
name: "xzc-1",
name: "firo-1",
args: args{
tx: testTx1,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
},
// FIXME: work around handle zerocoin spend as coinbase
// {
// name: "xzc-2",
// name: "firo-2",
// args: args{
// tx: testTx2,
// parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
// parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
// },
// },
{
name: "xzc-3",
name: "firo-3",
args: args{
tx: testTx3,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
},
}
@ -346,7 +448,7 @@ func TestGetAddrDescFromVoutForMint(t *testing.T) {
wantErr: false,
},
}
parser := NewZcoinParser(GetChainParams("main"), &btc.Configuration{})
parser := NewFiroParser(GetChainParams("main"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -396,7 +498,7 @@ func TestGetAddressesFromAddrDescForMint(t *testing.T) {
wantErr: false,
},
}
parser := NewZcoinParser(GetChainParams("main"), &btc.Configuration{})
parser := NewFiroParser(GetChainParams("main"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -421,7 +523,7 @@ func TestPackTx(t *testing.T) {
tx bchain.Tx
height uint32
blockTime int64
parser *ZcoinParser
parser *FiroParser
}
tests := []struct {
name string
@ -430,50 +532,72 @@ func TestPackTx(t *testing.T) {
wantErr bool
}{
{
name: "xzc-1",
name: "firo-1",
args: args{
tx: testTx1,
height: 100002,
blockTime: 1533980594,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTxPacked1,
wantErr: false,
},
// FIXME: work around handle zerocoin spend as coinbase
// {
// name: "xzc-2",
// name: "firo-2",
// args: args{
// tx: testTx2,
// height: 11002,
// blockTime: 1481277009,
// parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
// parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
// },
// want: testTxPacked2,
// wantErr: true,
// },
{
name: "xzc-3",
name: "firo-3",
args: args{
tx: testTx3,
height: 126202,
blockTime: 1547091829,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTxPacked3,
wantErr: false,
},
{
name: "xzc-coinbase",
name: "firo-coinbase",
args: args{
tx: testTx4,
height: 100001,
blockTime: 1533977563,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTxPacked4,
wantErr: false,
},
{
name: "firo-quorum-commitment-tx",
args: args{
tx: testTx5,
height: 5268,
blockTime: 1591752749,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: testTxPacked5,
wantErr: false,
},
{
name: "firo-special-coinbase-tx",
args: args{
tx: testTx6,
height: 5300,
blockTime: 1591762049,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: testTxPacked6,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -495,7 +619,7 @@ func TestPackTx(t *testing.T) {
func TestUnpackTx(t *testing.T) {
type args struct {
packedTx string
parser *ZcoinParser
parser *FiroParser
}
tests := []struct {
name string
@ -505,10 +629,10 @@ func TestUnpackTx(t *testing.T) {
wantErr bool
}{
{
name: "xzc-1",
name: "firo-1",
args: args{
packedTx: testTxPacked1,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx1,
want1: 100002,
@ -516,35 +640,55 @@ func TestUnpackTx(t *testing.T) {
},
// FIXME: work around handle zerocoin spend as coinbase
// {
// name: "xzc-2",
// name: "firo-2",
// args: args{
// packedTx: testTxPacked2,
// parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
// parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
// },
// want: &testTx2,
// want1: 11002,
// wantErr: true,
// },
{
name: "xzc-3",
name: "firo-3",
args: args{
packedTx: testTxPacked3,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx3,
want1: 126202,
wantErr: false,
},
{
name: "xzc-coinbase",
name: "firo-coinbase",
args: args{
packedTx: testTxPacked4,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx4,
want1: 100001,
wantErr: false,
},
{
name: "firo-special-tx",
args: args{
packedTx: testTxPacked5,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: &testTx5,
want1: 5268,
wantErr: false,
},
{
name: "firo-special-coinbase-tx",
args: args{
packedTx: testTxPacked6,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: &testTx6,
want1: 5300,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -570,7 +714,7 @@ func TestUnpackTx(t *testing.T) {
func TestParseBlock(t *testing.T) {
type args struct {
rawBlock string
parser *ZcoinParser
parser *FiroParser
}
tests := []struct {
name string
@ -583,7 +727,7 @@ func TestParseBlock(t *testing.T) {
name: "normal-block",
args: args{
rawBlock: rawBlock1,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &bchain.Block{
BlockHeader: bchain.BlockHeader{
@ -598,7 +742,7 @@ func TestParseBlock(t *testing.T) {
name: "spend-block",
args: args{
rawBlock: rawBlock2,
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &bchain.Block{
BlockHeader: bchain.BlockHeader{
@ -609,6 +753,21 @@ func TestParseBlock(t *testing.T) {
wantTxs: 4,
wantErr: false,
},
{
name: "special-tx-block",
args: args{
rawBlock: rawBlock3,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: &bchain.Block{
BlockHeader: bchain.BlockHeader{
Size: 200062,
Time: 1591752749,
},
},
wantTxs: 3,
wantErr: false,
},
}
for _, tt := range tests {
@ -632,3 +791,191 @@ func TestParseBlock(t *testing.T) {
})
}
}
func TestDecodeTransaction(t *testing.T) {
type args struct {
enc wire.MessageEncoding
rawTransaction string
parser *FiroParser
privacyType byte // 0 as non privacy
}
tests := []struct {
name string
args args
want bchain.Tx
wantErr bool
}{
{
name: "normal-transaction",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx1,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTx1,
},
{
name: "coinbase-firospend",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx2,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
privacyType: OpSigmaSpend,
},
want: testTx2,
},
{
name: "normal-transaction-2",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx3,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTx3,
},
{
name: "coinbase-transaction",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx4,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTx4,
},
{
name: "quorum-commitment-transaction",
args: args{
enc: wire.BaseEncoding,
rawTransaction: rawTestTx5,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTx5,
},
{
name: "quorum-commitment-transaction-witness",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx5,
parser: NewFiroParser(GetChainParams("main"), &btc.Configuration{}),
},
wantErr: true,
},
{
name: "special-coinbase",
args: args{
enc: wire.WitnessEncoding,
rawTransaction: rawTestTx6,
parser: NewFiroParser(GetChainParams("test"), &btc.Configuration{}),
},
want: testTx6,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, _ := hex.DecodeString(tt.args.rawTransaction)
r := bytes.NewReader(b)
msg := FiroMsgTx{}
err := msg.FiroDecode(r, 0, tt.args.enc)
if tt.wantErr {
if err == nil {
t.Errorf("Want error")
}
return
}
if err != nil {
t.Fatal(err)
}
got := tt.args.parser.TxFromFiroMsgTx(&msg, true)
if pErr := tt.args.parser.parseFiroTx(&got); pErr != nil {
t.Fatal(pErr)
}
if r.Len() != 0 {
t.Errorf("Expected EOF but there are remaining %d bytes to read", r.Len())
}
if len(got.Vin) != len(tt.want.Vin) {
t.Errorf("Check vin size, got %v, want %v", len(got.Vin), len(tt.want.Vin))
}
for i := 0; i != len(got.Vin); i++ {
if !reflect.DeepEqual(got.Vin[i].Addresses, tt.want.Vin[i].Addresses) {
t.Errorf("Check Addresses at input %d, got %v, want %v",
i, got.Vin[i].Addresses, tt.want.Vin[i].Addresses)
}
if !reflect.DeepEqual(got.Vin[i].Coinbase, tt.want.Vin[i].Coinbase) {
t.Errorf("Check Coinbase at input %d, got %v, want %v",
i, got.Vin[i].Coinbase, tt.want.Vin[i].Coinbase)
}
if !reflect.DeepEqual(got.Vin[i].ScriptSig, tt.want.Vin[i].ScriptSig) {
t.Errorf("Check ScriptSig at input %d, got %v, want %v",
i, got.Vin[i].ScriptSig, tt.want.Vin[i].ScriptSig)
}
if !reflect.DeepEqual(got.Vin[i].Sequence, tt.want.Vin[i].Sequence) {
t.Errorf("Check Sequence at input %d, got %v, want %v",
i, got.Vin[i].Sequence, tt.want.Vin[i].Sequence)
}
if tt.args.privacyType == 0 && !reflect.DeepEqual(got.Vin[i].Txid, tt.want.Vin[i].Txid) {
t.Errorf("Check Txid at input %d, got %v, want %v",
i, got.Vin[i].Txid, tt.want.Vin[i].Txid)
}
if tt.args.privacyType == 0 && !reflect.DeepEqual(got.Vin[i].Vout, tt.want.Vin[i].Vout) {
t.Errorf("Check Vout at input %d, got %v, want %v",
i, got.Vin[i].Vout, tt.want.Vin[i].Vout)
}
}
if len(got.Vout) != len(tt.want.Vout) {
t.Errorf("Check vout size, got %v, want %v", len(got.Vout), len(tt.want.Vout))
}
for i := 0; i != len(got.Vout); i++ {
if !reflect.DeepEqual(got.Vout[i].JsonValue, tt.want.Vout[i].JsonValue) {
t.Errorf("Check JsonValue at output %d, got %v, want %v",
i, got.Vout[i].JsonValue, tt.want.Vout[i].JsonValue)
}
if !reflect.DeepEqual(got.Vout[i].N, tt.want.Vout[i].N) {
t.Errorf("Check N at output %d, got %v, want %v",
i, got.Vout[i].N, tt.want.Vout[i].N)
}
// empty addresses and null should be the same
if !((len(got.Vout[i].ScriptPubKey.Addresses) == 0 && len(got.Vout[i].ScriptPubKey.Addresses) == len(tt.want.Vout[i].ScriptPubKey.Addresses)) ||
reflect.DeepEqual(got.Vout[i].ScriptPubKey.Addresses, tt.want.Vout[i].ScriptPubKey.Addresses)) {
t.Errorf("Check ScriptPubKey.Addresses at output %d, got %v, want %v",
i, got.Vout[i].ScriptPubKey.Addresses, tt.want.Vout[i].ScriptPubKey.Addresses)
}
if !reflect.DeepEqual(got.Vout[i].ScriptPubKey.Hex, tt.want.Vout[i].ScriptPubKey.Hex) {
t.Errorf("Check ScriptPubKey.Hex at output %d, got %v, want %v",
i, got.Vout[i].ScriptPubKey.Hex, tt.want.Vout[i].ScriptPubKey.Hex)
}
if !reflect.DeepEqual(got.Vout[i].ValueSat, tt.want.Vout[i].ValueSat) {
t.Errorf("Check ValueSat at output %d, got %v, want %v",
i, got.Vout[i].ValueSat, tt.want.Vout[i].ValueSat)
}
}
if got.LockTime != tt.want.LockTime {
t.Errorf("Check LockTime, got %v, want %v", got.LockTime, tt.want.LockTime)
}
if got.Txid != tt.want.Txid {
t.Errorf("Check TxId, got %v, want %v", got.Txid, tt.want.Txid)
}
})
}
}

View File

@ -1,4 +1,4 @@
package xzc
package firo
import (
"encoding/hex"
@ -6,23 +6,23 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
type ZcoinRPC struct {
type FiroRPC struct {
*btc.BitcoinRPC
}
func NewZcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
func NewFiroRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
// init base implementation
bc, err := btc.NewBitcoinRPC(config, pushHandler)
if err != nil {
return nil, err
}
// init zcoin implementation
zc := &ZcoinRPC{
// init firo implementation
zc := &FiroRPC{
BitcoinRPC: bc.(*btc.BitcoinRPC),
}
@ -35,7 +35,7 @@ func NewZcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationTyp
return zc, nil
}
func (zc *ZcoinRPC) Initialize() error {
func (zc *FiroRPC) Initialize() error {
ci, err := zc.GetChainInfo()
if err != nil {
return err
@ -45,7 +45,7 @@ func (zc *ZcoinRPC) Initialize() error {
params := GetChainParams(chainName)
// always create parser
zc.Parser = NewZcoinParser(params, zc.ChainConfig)
zc.Parser = NewFiroParser(params, zc.ChainConfig)
// parameters for getInfo request
if params.Net == MainnetMagic {
@ -61,7 +61,7 @@ func (zc *ZcoinRPC) Initialize() error {
return nil
}
func (zc *ZcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
func (zc *FiroRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error
if hash == "" {
@ -96,7 +96,7 @@ func (zc *ZcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error)
return block, nil
}
func (zc *ZcoinRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) {
func (zc *FiroRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) {
glog.V(1).Info("rpc: getblock (verbosity=true) ", hash)
res := btc.ResGetBlockInfo{}
@ -117,7 +117,7 @@ func (zc *ZcoinRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) {
return &res.Result, nil
}
func (zc *ZcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
func (zc *FiroRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
data, err := zc.GetBlockRaw(hash)
if err != nil {
return nil, err
@ -134,7 +134,7 @@ func (zc *ZcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.B
return block, nil
}
func (zc *ZcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
func (zc *FiroRPC) GetBlockRaw(hash string) ([]byte, error) {
glog.V(1).Info("rpc: getblock (verbosity=false) ", hash)
res := btc.ResGetBlockRaw{}
@ -155,7 +155,7 @@ func (zc *ZcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
return hex.DecodeString(res.Result)
}
func (zc *ZcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
func (zc *FiroRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
glog.V(1).Info("rpc: getrawtransaction nonverbose ", txid)
res := btc.ResGetRawTransactionNonverbose{}
@ -183,7 +183,7 @@ func (zc *ZcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
return tx, nil
}
func (zc *ZcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) {
func (zc *FiroRPC) GetTransaction(txid string) (*bchain.Tx, error) {
r, err := zc.getRawTransaction(txid)
if err != nil {
return nil, err
@ -198,14 +198,14 @@ func (zc *ZcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) {
return tx, nil
}
func (zc *ZcoinRPC) GetTransactionSpecific(tx *bchain.Tx) (json.RawMessage, error) {
func (zc *FiroRPC) GetTransactionSpecific(tx *bchain.Tx) (json.RawMessage, error) {
if csd, ok := tx.CoinSpecificData.(json.RawMessage); ok {
return csd, nil
}
return zc.getRawTransaction(tx.Txid)
}
func (zc *ZcoinRPC) getRawTransaction(txid string) (json.RawMessage, error) {
func (zc *FiroRPC) getRawTransaction(txid string) (json.RawMessage, error) {
glog.V(1).Info("rpc: getrawtransaction ", txid)
res := btc.ResGetRawTransaction{}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,8 +3,8 @@ package flo
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -9,7 +9,7 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// FloRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package fujicoin
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// FujicoinRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package gamecredits
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// GameCreditsRPC is an interface to JSON-RPC bitcoind service.

View File

@ -4,8 +4,8 @@ import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/base58"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -11,8 +11,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
var (

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// GroestlcoinRPC is an interface to JSON-RPC service

View File

@ -3,8 +3,8 @@ package koto
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -11,8 +11,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
var (

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// KotoRPC is an interface to JSON-RPC bitcoind service

View File

@ -8,8 +8,8 @@ import (
"github.com/martinboehm/btcd/txscript"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
const (

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -5,8 +5,8 @@ import (
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// LiquidRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package litecoin
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// LitecoinRPC is an interface to JSON-RPC bitcoind service.

View File

@ -3,7 +3,7 @@ package monacoin
import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// MonacoinRPC is an interface to JSON-RPC bitcoind service.

View File

@ -9,9 +9,9 @@ import (
"github.com/juju/errors"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
const (

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// MonetaryUnitRPC is an interface to JSON-RPC bitcoind service.

View File

@ -5,9 +5,9 @@ import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
// magic numbers

View File

@ -10,8 +10,8 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"github.com/golang/glog"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
// MyriadRPC is an interface to JSON-RPC bitcoind service.

View File

@ -5,9 +5,9 @@ import (
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
"spacecruft.org/spacecruft/blockbook/bchain"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/utils"
)
const (

View File

@ -13,7 +13,7 @@ import (
"testing"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain/coins/btc"
"spacecruft.org/spacecruft/blockbook/bchain/coins/btc"
)
func TestMain(m *testing.M) {

Some files were not shown because too many files have changed in this diff Show More