Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1Yl1jp-0002Wv-4O for bitcoin-development@lists.sourceforge.net; Wed, 22 Apr 2015 20:59:17 +0000 X-ACL-Warn: Received: from mail-qg0-f47.google.com ([209.85.192.47]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1Yl1jm-00068P-9P for bitcoin-development@lists.sourceforge.net; Wed, 22 Apr 2015 20:59:17 +0000 Received: by qgeb100 with SMTP id b100so90012839qge.3 for ; Wed, 22 Apr 2015 13:59:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=ozhHztFhcssFbio133WlLREAPBtfLIHTNh4FwGygpNI=; b=WRblw3cJ1npmKZUR8jMQCiddFErex6NeoB3n+2oEkk2t0LFyX1YhLzmdCAvE5L0VgF lQks7yoaRVMl5DNOPXDK3YJd6v9TsI9F6/lbw21cYxk3gFNFWz9ZftY/Qf/YICkws7Z+ IUC6qHgtAVmlXcLf+TjRz4/O6H0ilf65u1U23ZMt/bophIEKj+YzTCdfvouYqMWnLOZY YEz9i6W9NQ8wXeinqF/1dkIRLsMsBpka5cbjc6B18TVOpGgVXdULbCz/2AbwU67hOovb mRRj2KEbakMBsshUjA+HhsPTwKhhSKHfkrro7m/hW75KzG+rcjotIlj6A9xia3p+4+x+ aRsw== X-Gm-Message-State: ALoCoQmQu4NOO3MgVgd94DynBkgJncTnT1IpMFTrRpvSgQqRqTQv2/34de4/7/zj9bBQN2r6d9qU MIME-Version: 1.0 X-Received: by 10.55.20.215 with SMTP id 84mr52246298qku.51.1429733027146; Wed, 22 Apr 2015 13:03:47 -0700 (PDT) Received: by 10.96.145.9 with HTTP; Wed, 22 Apr 2015 13:03:47 -0700 (PDT) In-Reply-To: References: Date: Wed, 22 Apr 2015 22:03:47 +0200 Message-ID: From: Kalle Rosenbaum To: Bitcoin Dev Content-Type: multipart/alternative; boundary=001a1140093c350214051455a97c X-Spam-Score: 1.0 (+) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 1.0 HTML_MESSAGE BODY: HTML included in message X-Headers-End: 1Yl1jm-00068P-9P Subject: Re: [Bitcoin-development] Proof of Payment X-BeenThere: bitcoin-development@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Apr 2015 20:59:17 -0000 --001a1140093c350214051455a97c Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi again I've built a proof-of-concept for Proof of Payment. It's available at http://www.rosenbaum.se:8080. The site contains links to the source code for both the server and a Mycelium fork as well as pre-built apk:s. I'm still very interested in feedback on this, so please let me know what you think. Stuff that has come up so far, and my answers: * Some people think it's too complicated. I disagree. Using transactions as the data structure actually makes it simple to implement both on the server and in wallets. Just use existing wallet software to sign and verify PoPs. * Other ideas on Proof of Payment use a single key from the proven transaction, for example the first key from the first input of the transaction. This is problematic when multisig and other P2SH transactions are used. I also think that it's necessary to use *all* credentials used for the transaction. Otherwise we wouldn't be sure that the sender actually have all the needed credentials. * Another suggestion is that a payment request from BIP70 is used as proof. That is possible, but it's reusable which makes it inappropriate to send over networks; If it is stolen somewhere, anyone can use it as many times they like. As stated in BIP70, the payment request is suitable for dispute resolution, more like a receipt. On the other hand, I think that PoP would fit nicely into the workflow of BIP70: a) Read a url for the PoP request, b) get the (possibly signed) PoP request. c) send the PoP through http POST to the URL in the PoP request, d) profit! * A thought of my own: The txid used in the PoP output is not strictly necessary. It's more of a convenience for the verifier of the PoP. Without it, the verifier would need to lookup the transaction based on the inputs of the PoP, Regards, Kalle Rosenbaum 2015-03-14 19:16 GMT+01:00 Kalle Rosenbaum : > Den 14 mar 2015 00:59 skrev "Patrick Mccorry (PGR)" < > patrick.mccorry@newcastle.ac.uk>: > > > > That all seems more complicated than it needs to be - the service you > are paying knows that it had received a payment from some public key Q > (regardless of script type, as all scripts require a public key). > > The service knows it had received a payment from Q1, Q2,...,Qn. A tx may > have multiple inputs and each input may have several public keys. > > > > > So I want to rent a movie, they send me a challenge and I respond with = a > zero knowledge proof to demonstrate that I am the owner of Q, and as they > know that Q made a payment - then there is a proof of payment - as this i= s > provided by the time stamped transaction on the blockchain - in this sens= e > you are bootstrapping trust from the blockchain. > > > > Ok. Without knowing much about zero knowledge proof, i guess you'd need a > challenge/response for each of the keys Q1,..,Qn. If we settle on only a > single key, what key from what input should we use? One input may be a > multisig (2 of 3) input. Is it ok to settle on only one of the multisig > keys? Probably not. I'd say that we need 2 of 3 signatures (just as in a > bitcoin transaction), and not necessarily the same two that made the > payment. > > > For all of your scenarios, a simple challenge-response scheme would > work. Adding an op_return makes the payment transaction worse as it is no= w > distinguishable on the blockchain - you want use information that is > already available on that transaction. > > I'm not sure I follow. Do you mean that it's a problem that the PoP itsel= f > reveals what transaction I'm proving? Well, maybe it is a problem under > some circumstances. The least you can do to protect yourself from reveali= ng > information to third party is to communicate over secure channels. Could > you please elaborate on this? > > Anyway, if both the client and the server knows what transaction to prove > (ad-sign example) you are right that the tx info is kind of redundant. Bu= t > if we don't send the tx hints from server to client, the client user must > manually select the transaction to prove which makes the user experience > worse. > > Thank you very much for your comments, > > /Kalle > > > > > Sent from my iPhone > > > > On 13 Mar 2015, at 19:58, Kalle Rosenbaum wrote: > > > >> Hi all, > >> > >> I've been thinking about how a person can prove that she has made a > payment. I came up with an idea I call Proof of Payment (PoP) and I would > highly appreciate your comments. Has something like this been discussed > somewhere before? > >> > >> Use cases > >> > >> There are several scenarios in which it would be useful to prove that > you have paid for something. For example: > >> A pre-paid hotel room where your PoP functions as a key to the door. > >> An online video rental service where you pay for a video and watch it > on any device. > >> An ad-sign where you pay in advance for e.g. 2-weeks exclusivity. > During this period you can upload new content to the sign whenever you li= ke > using PoP. > >> A lottery where all participants pay to the same address, and the > winner of the T-shirt is selected among the transactions to that address. > You exchange the T-shirt for a PoP for the winning transaction. > >> > >> These use cases can be achieved without any personal information (no > accounts, no e-mails, etc) being involved. > >> > >> Desirable properties: > >> A PoP should be generated on demand. > >> It should only be usable once to avoid issues due to theft. > >> It should be able to create a PoP for any payment, regardless of scrip= t > type (P2SH, P2PKH, etc.). > >> Current methods of proving a payment, as I know of: > >> BIP0070, The PaymentRequest together with the transactions fulfilling > the payment makes some sort of proof. However, it does not meet 1 or 2 an= d > it obviously only meets 3 if the payment is made through BIP0070. Also, > there's no standard way to request/provide the proof. > >> Signing messages, chosen by the entity that the proof is provided to, > with the private keys used to sign the transaction. This could meet 1 and= 2 > but probably not 3. This is not standardized either. > >> Proof of Payment, the data structure > >> > >> A proof of payment for a transaction T, PoP(T), is used to prove that > one has ownership of the credentials needed to unlock all the inputs of T= . > It has the exact same structure as a bitcoin transaction with the same > inputs as T and with a single OP_RETURN output: > >> > >> OP_RETURN PoP > >> > >> | Field | Size [B] | Description | > >> |-----------|----------|------------------------------------| > >> | PoP | 3 | Literal identifying this as a PoP | > >> | | 32 | The transaction to Prove | > >> | | 5 | Unsigned integer | > >> > >> The PoP is signed using the same signing process that is used for > bitcoin transactions. The purpose of the nonce is to make it harder to us= e > a stolen PoP. Once the PoP has reached the destination, that PoP is usele= ss > since the destination will generate a new nonce for every PoP. > >> > >> Proof of Payment, the process > >> A proof of payment request is sent from the server to the wallet. The > request contains: > >> a random nonce > >> a destination where to send the PoP, for example a https URL > >> data hinting the wallet which transaction to create a proof for. For > example: > >> txid, if known by the server > >> PaymentRequest.PaymentDetails.merchant_data (in case of a BIP0070 > payment) > >> amount > >> label, message or other information from a BIP0021 URL > >> The wallet identifies the transaction T, if possible. Otherwise asks > the user to select among the ones that fit the hints in 1.3. > >> The wallet checks that T is on the blockchain, meaning all the inputs > are spent. > >> The wallet creates an unsigned PoP (UPoP) for T, and asks the user to > sign it. > >> The user confirms > >> The UPoP(T) is signed by the wallet, creating PoP(T). > >> The PoP is sent to the destination in 1.2. > >> The server receiving the PoP validates it and responds with =E2=80=9Cv= alid=E2=80=9D or > =E2=80=9Cinvalid=E2=80=9D > >> The wallet displays the response in some way to the user. > >> Remarks: > >> The method of transferring the PoP request at step 1 is not very well > thought through, but I think we can extend BIP0021 to cater for this. For > example read a URI, representing a PoP request, using QR code or NFC. A > more advanced approach would be to extend BIP0070. > >> The nonce must be randomly generated by the server for every new PoP > request. > >> Validating a PoP > >> > >> The server needs to validate the PoP and reply with =E2=80=9Cvalid=E2= =80=9D or > =E2=80=9Cinvalid=E2=80=9D. That process is outlined below: > >> Check the format of the PoP. It must pass normal transaction checks, > except for the inputs being already spent. > >> Check the output script. It must conform to the OP_RETURN output forma= t > outlined above. > >> Check that the nonce is the same as the one you requested. > >> Check that the txid in the output is the transaction you actually want > proof for. If you don=E2=80=99t know what transaction you want proof for,= check > that the transaction actually pays for the product/service you deliver (i= n > the video rental case, find the transaction among all payments for that > specific video). > >> Check that the inputs of the PoP are exactly the same as in transactio= n > T. > >> Check the signatures of all the inputs, as would be done on a normal > transaction. > >> If the signatures are valid, the PoP is valid. > >> Security issues > >> Someone can intercept the PoP-request and change the destination so > that the user sends the PoP to the bad actor. > >> Someone can intercept the PoP-request and change for example the txid > to trick the user to sign a PoP for another transaction than the intended= . > This can of course be avoided by actually looking at the UPoP before > signing it. The bad actor could also set hints for a transaction that the > user didn=E2=80=99t make, resulting in a broken service. > >> Someone can steal a PoP and try to use the service hoping to get a > matching nonce. Probability per try: 1/(2^40). The server should have > mechanism for detecting a brute force attack of this kind, or at least sl= ow > down the process by delaying the PoP request by some 100 ms or so. > >> Even if a wallet has no funds it might still be valuable as a generato= r > for PoPs. This makes it important to keep the security of the wallet afte= r > it has been emptied. > >> The first two issues are the same as for traditional bitcoin payments. > They could be mitigated by using secure connections and possibly also > extending BIP0070 to support PoPs. > >> > >> Further work > >> Figure out how to make use of, and extend, BIP0070 for the purpose of > PoPs > >> Define an extension for BIP0021 to support PoP requests (something > along the lines of BIP0072) > >> Implement a proof-of-concept > >> Possibly propose BIPs for the different parts. > >> Looking forward to reading your comments > >> Regards, > >> Kalle Rosenbaum > >> > >> > -------------------------------------------------------------------------= ----- > >> Dive into the World of Parallel Programming The Go Parallel Website, > sponsored > >> by Intel and developed in partnership with Slashdot Media, is your hub > for all > >> things parallel software development, from weekly thought leadership > blogs to > >> news, videos, case studies, tutorials and more. Take a look and join > the > >> conversation now. http://goparallel.sourceforge.net/ > >> > >> _______________________________________________ > >> Bitcoin-development mailing list > >> Bitcoin-development@lists.sourceforge.net > >> https://lists.sourceforge.net/lists/listinfo/bitcoin-development > --001a1140093c350214051455a97c Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi again

I've built a proof-of-concept for Proo= f of Payment. It's available at http://www.rosenbaum.se:8080. The site contains lin= ks to the source code for both the server and a Mycelium fork as well as pr= e-built apk:s.

I'm still very interested in feedback on this, so= please let me know what you think.

Stuff that has come up so far, a= nd my answers:

* Some people think it's too complicated. I disagree. Using transactions= =20 as the data structure actually makes it simple to implement both on the=20 server and in wallets. Just use existing wallet software to sign and=20 verify PoPs.

* Other ideas on Proof of Payment use a single key from the proven transaction, for example the first key from the=20 first input of the transaction. This is problematic when multisig and=20 other P2SH transactions are used. I also think that it's necessary to u= se all=20 credentials used for the transaction. Otherwise we wouldn't be sure tha= t the sender actually have all the needed credentials.

* Another sug= gestion is that a payment request=20 from BIP70 is used as proof. That is possible, but it's reusable which= =20 makes it inappropriate to send over networks; If it is stolen somewhere, anyone can use it as many times they like. As stated in BIP70, the=20 payment request is suitable for dispute resolution, more like a receipt. On= the other hand, I think that PoP would fit nicely into the workflow of BIP= 70: a) Read a url for the PoP request, b) get the (possibly signed) PoP re= quest. c) send the PoP through http POST to the URL in the PoP request, d) = profit!
=C2=A0
* A thought of my own: The txid used in the PoP output is not strictly=20 necessary. It's more of a convenience for the verifier of the PoP.=20 Without it, the verifier would need to lookup the transaction based on=20 the inputs of the PoP,

Regards,
Kalle= Rosenbaum

2= 015-03-14 19:16 GMT+01:00 Kalle Rosenbaum <kalle@rosenbaum.se>:
Den 14 mar 2015 00:59 skrev "Patrick Mccorry (PGR)" = <pa= trick.mccorry@newcastle.ac.uk>:
>
> That all seems more complicated than it needs to be - the service you = are paying knows that it had received a payment from some public key Q (reg= ardless of script type, as all scripts require a public key).

The service knows it had received a payment from Q1, = Q2,...,Qn. A tx may have multiple inputs and each input may have several pu= blic keys.

>
> So I want to rent a movie, they send me a challenge and I respond with= a zero knowledge proof to demonstrate that I am the owner of Q, and as the= y know that Q made a payment - then there is a proof of payment - as this i= s provided by the time stamped transaction on the blockchain - in this sens= e you are bootstrapping trust from the blockchain.
>

Ok. Without knowing much about zero knowledge proof, = i guess you'd need a challenge/response for each of the keys Q1,..,Qn. = If we settle on only a single key, what key from what input should we use? = One input may be a multisig (2 of 3) input. Is it ok to settle on only one = of the multisig keys? Probably not. I'd say that we need 2 of 3 signatu= res (just as in a bitcoin transaction), and not necessarily the same two th= at made the payment.

> For all of your scenarios, a simple challenge-response scheme wou= ld work. Adding an op_return makes the payment transaction worse as it is n= ow distinguishable on the blockchain - you want use information that is alr= eady available on that transaction.

I'm not sure I fo= llow. Do you mean that it's a problem that the PoP itself reveals what = transaction I'm proving? Well, maybe it is a problem under some circums= tances. The least you can do to protect yourself from revealing information= to third party is to communicate over secure channels. Could you please el= aborate on this?

Anyway, if both the client and the server knows what= transaction to prove (ad-sign example) you are right that the tx info is k= ind of redundant. But if we don't send the tx hints from server to clie= nt, the client user must manually select the transaction to prove which mak= es the user experience worse.

Thank you very much for your comme= nts,

/Kalle

>
> Sent from my iPhone
>
> On 13 Mar 2015, at 19:58, Kalle Rosenbaum <kalle@rosenbaum.se> wrote:
>
>> Hi all,
>>
>> I've been thinking about how a person can prove that she has m= ade a payment. I came up with an idea I call Proof of Payment (PoP) and I w= ould highly appreciate your comments. Has something like this been discusse= d somewhere before?
>>
>> Use cases
>>
>> There are several scenarios in which it would be useful to prove t= hat you have paid for something. For example:
>> A pre-paid hotel room where your PoP functions as a key to the doo= r.
>> An online video rental service where you pay for a video and watch= it on any device.
>> An ad-sign where you pay in advance for e.g. 2-weeks exclusivity. = During this period you can upload new content to the sign whenever you like= using PoP.
>> A lottery where all participants pay to the same address, and the = winner of the T-shirt is selected among the transactions to that address. Y= ou exchange the T-shirt for a PoP for the winning transaction.
>>
>> These use cases can be achieved without any personal information (= no accounts, no e-mails, etc) being involved.
>>
>> Desirable properties:
>> A PoP should be generated on demand.
>> It should only be usable once to avoid issues due to theft.
>> It should be able to create a PoP for any payment, regardless of s= cript type (P2SH, P2PKH, etc.).
>> Current methods of proving a payment, as I know of:
>> BIP0070, The PaymentRequest together with the transactions fulfill= ing the payment makes some sort of proof. However, it does not meet 1 or 2 = and it obviously only meets 3 if the payment is made through BIP0070. Also,= there's no standard way to request/provide the proof.
>> Signing messages, chosen by the entity that the proof is provided = to, with the private keys used to sign the transaction. This could meet 1 a= nd 2 but probably not 3. This is not standardized either.
>> Proof of Payment, the data structure
>>
>> A proof of payment for a transaction T, PoP(T), is used to prove t= hat one has ownership of the credentials needed to unlock all the inputs of= T. It has the exact same structure as a bitcoin transaction with the same = inputs as T and with a single OP_RETURN output:
>>
>> OP_RETURN PoP <txid> <nonce>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
>> | Field =C2=A0 =C2=A0 | Size [B] | Description=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |
>> |-----------|----------|------------------------------------|
>> | PoP=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 3=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 | Literal identifying this as a PoP=C2=A0 |
>> | <txid> =C2=A0=C2=A0 | 32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 | The transaction to Prove=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |
>> | <nonce>=C2=A0=C2=A0 | 5=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 | Unsigned integer=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |
>>
>> The PoP is signed using the same signing process that is used for = bitcoin transactions. The purpose of the nonce is to make it harder to use = a stolen PoP. Once the PoP has reached the destination, that PoP is useless= since the destination will generate a new nonce for every PoP.
>>
>> Proof of Payment, the process
>> A proof of payment request is sent from the server to the wallet. = The request contains:
>> a random nonce
>> a destination where to send the PoP, for example a https URL
>> data hinting the wallet which transaction to create a proof for. F= or example:
>> txid, if known by the server
>> PaymentRequest.PaymentDetails.merchant_data (in case of a BIP0070 = payment)
>> amount
>> label, message or other information from a BIP0021 URL
>> The wallet identifies the transaction T, if possible. Otherwise as= ks the user to select among the ones that fit the hints in 1.3.
>> The wallet checks that T is on the blockchain, meaning all the inp= uts are spent.
>> The wallet creates an unsigned PoP (UPoP) for T, and asks the user= to sign it.
>> The user confirms
>> The UPoP(T) is signed by the wallet, creating PoP(T).
>> The PoP is sent to the destination in 1.2.
>> The server receiving the PoP validates it and responds with =E2=80= =9Cvalid=E2=80=9D or =E2=80=9Cinvalid=E2=80=9D
>> The wallet displays the response in some way to the user.
>> Remarks:
>> The method of transferring the PoP request at step 1 is not very w= ell thought through, but I think we can extend BIP0021 to cater for this. F= or example read a URI, representing a PoP request, using QR code or NFC. A = more advanced approach would be to extend BIP0070.
>> The nonce must be randomly generated by the server for every new P= oP request.
>> Validating a PoP
>>
>> The server needs to validate the PoP and reply with =E2=80=9Cvalid= =E2=80=9D or =E2=80=9Cinvalid=E2=80=9D. That process is outlined below:
>> Check the format of the PoP. It must pass normal transaction check= s, except for the inputs being already spent.
>> Check the output script. It must conform to the OP_RETURN output f= ormat outlined above.
>> Check that the nonce is the same as the one you requested.
>> Check that the txid in the output is the transaction you actually = want proof for. If you don=E2=80=99t know what transaction you want proof f= or, check that the transaction actually pays for the product/service you de= liver (in the video rental case, find the transaction among all payments fo= r that specific video).
>> Check that the inputs of the PoP are exactly the same as in transa= ction T.
>> Check the signatures of all the inputs, as would be done on a norm= al transaction.
>> If the signatures are valid, the PoP is valid.
>> Security issues
>> Someone can intercept the PoP-request and change the destination s= o that the user sends the PoP to the bad actor.
>> Someone can intercept the PoP-request and change for example the t= xid to trick the user to sign a PoP for another transaction than the intend= ed. This can of course be avoided by actually looking at the UPoP before si= gning it. The bad actor could also set hints for a transaction that the use= r didn=E2=80=99t make, resulting in a broken service.
>> Someone can steal a PoP and try to use the service hoping to get a= matching nonce. Probability per try: 1/(2^40). The server should have mech= anism for detecting a brute force attack of this kind, or at least slow dow= n the process by delaying the PoP request by some 100 ms or so.
>> Even if a wallet has no funds it might still be valuable as a gene= rator for PoPs. This makes it important to keep the security of the wallet = after it has been emptied.
>> The first two issues are the same as for traditional bitcoin payme= nts. They could be mitigated by using secure connections and possibly also = extending BIP0070 to support PoPs.
>>
>> Further work
>> Figure out how to make use of, and extend, BIP0070 for the purpose= of PoPs
>> Define an extension for BIP0021 to support PoP requests (something= along the lines of BIP0072)
>> Implement a proof-of-concept
>> Possibly propose BIPs for the different parts.
>> Looking forward to reading your comments
>> Regards,
>> Kalle Rosenbaum
>>
>> ------------------------------------------------------------------= ------------
>> Dive into the World of Parallel Programming The Go Parallel Websit= e, sponsored
>> by Intel and developed in partnership with Slashdot Media, is your= hub for all
>> things parallel software development, from weekly thought leadersh= ip blogs to
>> news, videos, case studies, tutorials and more. Take a look and jo= in the
>> conversation now. http://goparallel.sourceforge.net/
>>
>> _______________________________________________
>> Bitcoin-development mailing list
>> Bitcoin-development@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/b= itcoin-development


--001a1140093c350214051455a97c--