Skip to content

Commit

Permalink
add setTxFee, Stop, SignMessage, VerifyMessage, ValidateAddress, Wall…
Browse files Browse the repository at this point in the history
…etLock, WalletPassphraseChange

Signed-off-by: Stéphane Depierrepont <[email protected]>
  • Loading branch information
toorop committed May 26, 2014
1 parent f887543 commit 2cc7fe3
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 16 deletions.
84 changes: 73 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,92 @@
bitcoind
===========
[![Build Status](https://travis-ci.org/Toorop/go-bitcoind.svg)](https://travis-ci.org/Toorop/go-bitcoind)


A Golang client library wrapping the bitcoind JSON RPC API

Work in progress, stay tuned

Installation
-----
$ go get https://github.com/Toorop/go-bitcoind


Usage
----

package main

import (
"github.com/toorop/go-bitcoind"
"log"
)

const (
SERVER_HOST = "You server host"
SERVER_PORT = port (int)
USER = "user"
PASSWD = "passwd"
USESSL = false
WALLET_PASSPHRASE = "WalletPassphrase"
)

func main() {
bc, err := bitcoind.New(SERVER_HOST, SERVER_PORT, USER, PASSWD, USESSL)
if err != nil {
log.Fatalln(err)
}

//walletpassphrase
err = bc.WalletPassphrase(WALLET_PASSPHRASE, 3600)
log.Println(err)

// backupwallet
err = bc.BackupWallet("/tmp/wallet.dat")
log.Println(err)


// dumpprivkey
privKey, err := bc.DumpPrivKey("1KU5DX7jKECLxh1nYhmQ7CahY7GMNMVLP3")
log.Println(err, privKey)

}

Mores examples in example.go (in examples folder)

Documentation
-----
[![GoDoc](https://godoc.org/github.com/Toorop/go-bitcoind?status.png)](https://godoc.org/github.com/Toorop/go-bitcoind)
[![GoDoc](https://godoc.org/github.com/Toorop/go-bitcoind?status.png)](https://godoc.org/github.com/Toorop/go-bitcoind)

Unit tests
----
[![Build Status](https://travis-ci.org/Toorop/go-bitcoind.svg)](https://travis-ci.org/Toorop/go-bitcoind)

More than 100 unit tests are made.

To run tests:

$ go get github.com/onsi/ginkgo/ginkgo
$ go get github.com/onsi/gomega
$ ginkgo

Running Suite: Bitcoind Suite
=============================
Random Seed: 1401120770
Will run 112 of 112 specs

•••••••••••••••••••••••••••••••••••
Ran 112 of 112 Specs in 0.001 seconds
SUCCESS! -- 112 Passed | 0 Failed | 0 Pending | 0 Skipped PASS

Ginkgo ran in 10.856335553s
Test Suite Passed


Todo
-----
* https
* GetBlockTemplate
* sendrawtransaction
* signrawtransaction
* settxfee
* signmessage
* stop
* submitblock
* validateaddress
* verifymessage
* walletlock
* walletpassphrasechange

Donation
------
Expand Down
66 changes: 66 additions & 0 deletions bitcoind.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,74 @@ func (b *Bitcoind) SetGenerate(generate bool, genProcLimit int32) error {
return handleError(err, &r)
}

// SetTxFee set the transaction fee per kB
func (b *Bitcoind) SetTxFee(amount float64) error {
r, err := b.client.call("settxfee", []interface{}{amount})
return handleError(err, &r)
}

// Stop stop bitcoin server.
func (b *Bitcoind) Stop() error {
r, err := b.client.call("stop", nil)
return handleError(err, &r)
}

// SignMessage sign a message with the private key of an address
func (b *Bitcoind) SignMessage(address, message string) (sig string, err error) {
r, err := b.client.call("signmessage", []interface{}{address, message})
if err = handleError(err, &r); err != nil {
return
}
err = json.Unmarshal(r.Result, &sig)
return
}

// Verifymessage Verify a signed message.
func (b *Bitcoind) VerifyMessage(address, sign, message string) (success bool, err error) {
r, err := b.client.call("verifymessage", []interface{}{address, sign, message})
if err = handleError(err, &r); err != nil {
return
}
err = json.Unmarshal(r.Result, &success)
return
}

// ValidateAddressResponse represents a response to "validateaddress" call
type ValidateAddressResponse struct {
IsValid bool `json:"isvalid"`
Address string `json:"address"`
IsMine bool `json:"ismine"`
IsScript bool `json:"isscript"`
PubKey string `json:"pubkey"`
IsCompressed bool `json:"iscompressed"`
Account string `json:"account"`
}

// ValidateAddress return information about <bitcoinaddress>.
func (b *Bitcoind) ValidateAddress(address string) (va ValidateAddressResponse, err error) {
r, err := b.client.call("validateaddress", []interface{}{address})
if err = handleError(err, &r); err != nil {
return
}
err = json.Unmarshal(r.Result, &va)
return
}

// WalletLock Removes the wallet encryption key from memory, locking the wallet.
// After calling this method, you will need to call walletpassphrase again before being
// able to call any methods which require the wallet to be unlocked.
func (b *Bitcoind) WalletLock() error {
r, err := b.client.call("walletlock", nil)
return handleError(err, &r)
}

// walletPassphrase stores the wallet decryption key in memory for <timeout> seconds.
func (b *Bitcoind) WalletPassphrase(passPhrase string, timeout uint64) error {
r, err := b.client.call("walletpassphrase", []interface{}{passPhrase, timeout})
return handleError(err, &r)
}

func (b *Bitcoind) WalletPassphraseChange(oldPassphrase, newPassprhase string) error {
r, err := b.client.call("walletpassphrasechange", []interface{}{oldPassphrase, newPassprhase})
return handleError(err, &r)
}
149 changes: 147 additions & 2 deletions bitcoind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1904,7 +1904,132 @@ var _ = Describe("Bitcoind", func() {
})
})

/*Describe("walletpassphrase", func() {
Describe("Testing SetTxFee", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":true,"error":null,"id":1401115696421261167}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
err = bitcoindClient.SetTxFee(0.0001)
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
})
})

Describe("Testing SignMessage", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":"ILImxcrK6iELcUSqH9ntxGYrpd9MuYwx0rXnLHron1NEG9Jog36RbFCQzaRSO0/XXu6msoWiz4n1Q64kCNv4nH8=","error":null,"id":1401117539316610969}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
sig, err := bitcoindClient.SignMessage("1Pyizp4HK7Bfz7CdbSwHHtprk7Ghumhxmy", "test message")
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should return a string sig ", func() {
Expect(sig).Should(Equal("ILImxcrK6iELcUSqH9ntxGYrpd9MuYwx0rXnLHron1NEG9Jog36RbFCQzaRSO0/XXu6msoWiz4n1Q64kCNv4nH8="))
})
})
})

Describe("Testing Stop", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":"Bitcoin server stopping","error":null,"id":1401118273551801323}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
err = bitcoindClient.Stop()
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
})
})

Describe("Testing ValidateAddress", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":{"isvalid":true,"address":"1Pyizp4HK7Bfz7CdbSwHHtprk7Ghumhxmy","ismine":true,"isscript":false,"pubkey":"02dc7ecd8baec59cf018bf40d1e948519dc0dcf256eb3bc3ed121bc3ee83c98b01","iscompressed":true,"account":"tests"},"error":null,"id":1401119296578850111}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
resp, err := bitcoindClient.ValidateAddress("1Pyizp4HK7Bfz7CdbSwHHtprk7Ghumhxmy")
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should return a string sig ", func() {
Expect(resp).Should(Equal(ValidateAddressResponse{
IsValid: true,
Address: "1Pyizp4HK7Bfz7CdbSwHHtprk7Ghumhxmy",
IsMine: true,
IsScript: false,
PubKey: "02dc7ecd8baec59cf018bf40d1e948519dc0dcf256eb3bc3ed121bc3ee83c98b01",
IsCompressed: true,
Account: "tests",
}))
})
})
})

Describe("Testing VerifyMessage", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":true,"error":null,"id":1401117539369759914}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
success, err := bitcoindClient.VerifyMessage("1Pyizp4HK7Bfz7CdbSwHHtprk7Ghumhxmy", "fake_sig", "test message")
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
It("succes should be true", func() {
Expect(success).To(BeTrue())
})
})
})

Describe("Testing WalletLock", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":null,"error":null,"id":1401119933934255494}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
err = bitcoindClient.WalletLock()
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
})
})

Describe("walletpassphrase", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":null,"error":null,"id":1400433627531460562}`)
Expand All @@ -1920,5 +2045,25 @@ var _ = Describe("Bitcoind", func() {
Expect(err).NotTo(HaveOccurred())
})
})
})*/
})

Describe("Testing WalletPassphraseChange", func() {
Context("when success", func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `{"result":null,"error":null,"id":1401120599336429525}`)
})
ts, host, port, err := getNewTestServer(handler)
if err != nil {
log.Fatalln(err)
}
defer ts.Close()
bitcoindClient, _ := New(host, port, "x", "fake", false)
err = bitcoindClient.WalletPassphraseChange("fakePassPhrase", "fake passphrase")
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
})
})

// {"result":null,"error":null,"id":1401120599336429525}
})
5 changes: 2 additions & 3 deletions rpcClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,9 @@ func (c *rpcClient) call(method string, params interface{}) (rr rpcResponse, err
return
}
if resp.StatusCode != 200 {
err = errors.New(resp.Status)
err = errors.New("HTTP error: " + resp.Status)
return
}

err = json.Unmarshal(data, &rr)

return
}

0 comments on commit 2cc7fe3

Please sign in to comment.