There would probably be an alert sent out by the developers and then they would decide whether to roll back the blockchain back to the fork point, or choose one chain and set checkpoints into the software to make sure that is the one used.
In this situation it would be hard to avoid using the longest chain, especially if it was a significant difference. Including a checkpoint in the software would be like declaring war on the majority hashrate, and they may well respond by locking out the minority until they'd got the money they thought they were owed... This isn't entirely academic, because the majority hashrate is in an authoritarian regime that's long been propped up by a good economy, and that economy isn't looking good. If they felt at serious risk of a revolution it's not hard to imagine them turning off access to the outside world. I think the upshot would be that you couldn't safely use bitcoin until the situation sorted itself out.
|
|
|
When was the last time an invalid block was created on purpose?
Presumably in the BIP 66 fork the miners would have put up, and ultimately lost, their guarantee, because they were oblivious to the fact that the network had upgraded on them.
|
|
|
I keep clicking on this thread and expecting to see something starting "I'd tell you a blockchain joke but..."
Can someone help out with the punchline?
|
|
|
Another interesting thought in this area is Greg Maxwell's suggestion that you could make the block difficulty depend on the block size. A transaction with high fees could not only ensure you get into the next block, it also could increase the probability that the next block will be found quickly, because miners are incentivised to drop their block size and reduce the difficulty to increase their chances of collecting the fee. This also scales up in the opposite direction where needed to handle a capacity crunch, because if you've got a long tail of transactions waiting with a reasonable cumulative fee, you're incentivized to stretch out the block size to accomodate them.
|
|
|
I don't know if this is related but something seems to have changed in the way pybitcointool serializes scripts since I was working with this around: https://github.com/vbuterin/pybitcointools/commit/87aaf6dc3f38d853dd8cb324a4eaf72ae309d322...which I think is still the version you get if you do pip install pybitcointool (This is before the name changed to "bitcoin".) I haven't had a chance to get to the bottom of this and it may be that the old version is broken and the new one is right, but you might like to try comparing what you get with the old version.
|
|
|
This is cool. I'm not normally a big fan of bitcoin for point-of-sale but where I think it's really nice is for trust-but-audit-or-shame scenarios. The classic one would be a bitcoin parking meter, consisting of... a QR code in front of the space.
That said, I wonder whether people would rather use this than just use the QR code to send the customer to a web page.
|
|
|
A soft fork adds limitations that make previously-valid blocks invalid, so miners who aren't enforcing _any_ limitations are effectively on the "didn't upgrade" side. But a hard fork makes blocks that were previously invalid valid, so if 75% are advertising big-block support but some miners who haven't advertised that aren't validating at all, you'll actually have more than 75% mining the big-block main chain.
PS. In reality you'll have much more than 75% advertising big-block support once the switch-over comes (if it ever does) because most miners will upgrade during the 2-week grace period rather than be left mining dead coins.
PPS. After losing money this way I doubt many miners will continue running with verification completely switched off; They have much better alternatives either by getting blocks propagated faster and mining normally or by at least verifying in parallel and giving up trying to mine on top of blocks once they've found that they're invalid.
Fair enough, but don't forget MPEX, etc. plan to sabotage any attempt to raise max_blocksize. IE, they will falsely advertise >1MB compliance in order to (prematurely) bait the hard fork into a prearranged GavinCoin Short kill box. This is not a serious suggestion. You'd need 25% of mining power to pull it off even if zero miners switched in the grace period, but since most of the remaining miners will switch during the grace period you need more like [conservatively] 45%. MPEX control approximately 0% of mining power, and if they were able to acquire more than 25% they could block bigger blocks the normal way by refusing to upgrade.
|
|
|
Actually it works the other way around. A soft fork adds limitations that make previously-valid blocks invalid, so miners who aren't enforcing _any_ limitations are effectively on the "didn't upgrade" side. But a hard fork makes blocks that were previously invalid valid, so if 75% are advertising big-block support but some miners who haven't advertised that aren't validating at all, you'll actually have more than 75% mining the big-block main chain. PS. In reality you'll have much more than 75% advertising big-block support once the switch-over comes (if it ever does) because most miners will upgrade during the 2-week grace period rather than be left mining dead coins. PPS. After losing money this way I doubt many miners will continue running with verification completely switched off; They have much better alternatives either by getting blocks propagated faster and mining normally or by at least verifying in parallel and giving up trying to mine on top of blocks once they've found that they're invalid.
|
|
|
If we're making drastic changes it may be worthwhile to target balance of unspent outputs instead of / as well as block size, since UTXO size seems to be a more likely bottleneck than the network, unfortunate American core devs still connected to the internet using 1870s-style copper wires notwithstanding.
|
|
|
The real-world implementation of the keypairs-instead-of-passwords idea is client-side SSL certificates. The ability to do this has been in servers and browsers since forever. Unfortunately the user experience has generally been a massive PITA, with the result that they're mostly confined to corporate or government systems where the security-conscious IT Department can mandate their use and the users have to suck it up. A lot of these problems are probably fixable, but as with bitcoin, the UX issues involved in generating keys and storing them securely without bollocksing it up aren't trivial. There's a good summary here - the comments are worth a read, too. http://pilif.github.io/2008/05/why-is-nobody-using-ssl-client-certificates/Thanks, I'll have to dig into this. I figured I wasn't treading new ground, just can't figure out why it should be so difficult. The depressing thing about this is that the <keygen> tag (for creating keypairs on the browser and sending the public key to the server) has been around since 1996, but here we are in 2015 and we're still waiting for something without horribly broken usability. If some smart marketer can turn the whole bitcoin-technology-but-not-bitcoin hype into a way to get this old technology actually usefully adopted that would be a huge win... We should tell people Satoshi invented a basic authentication logout button while we're at it...
|
|
|
The real-world implementation of the keypairs-instead-of-passwords idea is client-side SSL certificates. The ability to do this has been in servers and browsers since forever. Unfortunately the user experience has generally been a massive PITA, with the result that they're mostly confined to corporate or government systems where the security-conscious IT Department can mandate their use and the users have to suck it up. A lot of these problems are probably fixable, but as with bitcoin, the UX issues involved in generating keys and storing them securely without bollocksing it up aren't trivial. There's a good summary here - the comments are worth a read, too. http://pilif.github.io/2008/05/why-is-nobody-using-ssl-client-certificates/
|
|
|
If all parties use HD wallets, you can use HDM. Then you don't have to remember the public keys that were used because you can regenerate them.
In theory yes, but when multiple parties are involved you're at least going to need to store _something_ related to the other party, even if you've removed the need to store many things. Deterministic wallets are actually making this problem more pressing, because if you already have to store and back up a bunch of random private keys then you presumably already have a process for storing and backing up new data, but nowadays people reasonably expect not to lose funds unless they lose their seed.
|
|
|
A lot of people out there are starting to do more interesting stuff with multi-sig, often involving multiple parties combining their keys in transactions to create a P2SH address.
When one of the parties comes to actually spend whatever's been sent to that P2SH address, they're going to need the original public keys to recreate the P2SH address, even if they don't actually need the corresponding private keys that would allow them to sign. So this information needs to be stored somewhere. We want this to be around even if whatever site may have helped set up the transaction has gone away, and it probably doesn't need to be secret, since it's ultimately going to show up on the blockchain anyway. I guess that implies we want it to be mirrored in several or more places, ideally run by a mix of different people in a mix of jurisdictions.
I know there are a bunch of clever data alt-coins and things in development, but has anyone got any suggestions for something practical we can use for a web app right now? We all love P2P but if there isn't a good fully P2P solution I think the "reasonably trustworthy vendor" model is OK here, as long as you have the data synced to reasonably diverse reasonably trustworthy vendors.
Basically I guess we're looking at an append-only public data storage for shortish bits of data. (I guess the fiddly bit is how you do anti-spam, since it's hard to squeeze "pay the data storage guy" in some of these workflows until you actually do the redeem.)
I know I'm not the first person to be feeling pain here - any suggestions for something that would be good to use, or if not any thoughts about what would be a useful thing to build?
|
|
|
Now that redeem scripts can be arbitrary, I think OP_EVAL might find a new usage. Imagine you create a redeem that can be proven by anybody knowing some secret OR owning a specific bitcoin address. Script redeemScript = new Script( "OP_IF " + "OP_HASH256 " + Op.GetPushOp(secretHash) + " OP_EQUAL " + "OP_ELSE " + address.ScriptPubKey + " " + "OP_ENDIF");
Such script works fine if address is a P2PKH, however if address is a P2SH then the only condition to satisfy the ELSE branch is to know the redeem script of address. This could be fixed with OP_EVAL by the following way. (assuming address is P2SH) Script redeemScript = new Script( "OP_IF " + "OP_HASH256 " + Op.GetPushOp(secretHash) + " OP_EQUAL " + "OP_ELSE " "OP_DUP " + address.ScriptPubKey + " OP_EVAL" + "OP_ENDIF");
Sure, we could also use multi sig or public key ScriptPubKey directly in the ELSE branch, but they might not necessarily be known by the builder of the redeem script. You could of course put the content that would have been hashed directly into one of the branches of the OP_IF, rather than trying to do these recursive script hashes. Presumably one of the parties to the transaction knows what needs to go in there, because otherwise they won't be able to spend it. That's what I do here for Reality Keys transactions (output spendable by Alice+Yes or Bob+No or Alice+Bob): https://github.com/edmundedgar/bitcoin-branching-transaction-builder/
|
|
|
Sweet. We should probably: 1) Write a test for the other branch as well 2) Try sending the tx to a 0.10 node before using blochain.info/pushtx on it to prove that the network will really take these things when it starts to upgrade.
1) Ok. I have to learn how to do a push request (I suck at GIT) and I'll make a suggestion to your test. 2) the blockchain.info method is a kind of a cheat ;-) But if it works ;-) but I'd LOVE to test that. I'm just happy it's working (and it worked. I got my 2 cents ;-) Who tests on the testnet any more ;-) P.S. Your library will be talked about at tomorrow's Miami Bitcoin hackathon cause it's amazing. Thank you so much for helping me with this. OK, I just went ahead and added those tests myself. The redeem transaction went fine through a stock bitcoin 0.10, and enough of the network seems to have relayed it for it to show up on blockchain.info. https://blockchain.info/tx/c6b283ed4f2742b3c5aca31380daa423e89620e95a53cddf3d81338dcca95b8cEdit to add: And mined, also by Eligius. Discus Fish doesn't seem to be a thing any more...
|
|
|
Who tests on the testnet any more ;-)
I'm liking this system where an address I control is hard-coded in the test code, and people test their code by sending real money to it...
|
|
|
Just updating the group. We have created successfully a MultiSig Signature from JUST the Bitcoin Addresses (I think we're the first to do that, can't find anyone else online doing this.) NO PUBKEY WAS USED (well the PubKey HASH was using, but not the original uncompressed full PubKey) See transactions IN (the first from edmundedgar with the public Keys and the second from ME using the code below) https://blockchain.info/address/3PcxJeW5f6Tp4mVAXe4ggGRvDREAPCMF4oThanks of course to everyone. And especially to edmundedgar for his amazing code examples INCLUDING his private keys (which makes live easier) You need to do a: 1) download edmundedgar's Bitcoin Branching Transaction builder: https://github.com/edmundedgar/bitcoin-branching-transaction-builder2) run "npm install bitcoinjs-lib" on that root directory 3) Make an app.js in the root of that project with the following code below (of course you have to have NODEjs installed) var bitcoin = require('bitcoinjs-lib'); var BranchingTransactionBuilder = require('./src/branching_transaction_builder'); var ECKey = bitcoin.ECKey; var Address = bitcoin.Address; var scripts = bitcoin.scripts;
var BitcoinAddress1 = "1Fratqwo3Bu2FwMBzAex8WgDbmmGgJYLGH"; var BitcoinAddress2 = "112jFbM3Lp3qRSjezGFCv2rejT3UQ6rH5Z";
var addr1 = Address.fromBase58Check(BitcoinAddress1); var addr2 = Address.fromBase58Check(BitcoinAddress2);
var branch1 = scripts.pubKeyHashOutput(addr1.hash); var branch2 = scripts.pubKeyHashOutput(addr2.hash);
var branch_builder = new BranchingTransactionBuilder(); branch_builder.addSubScript(branch1); branch_builder.addSubScript(branch2); var branch_redeem_script = branch_builder.script();
var scriptPubKey = bitcoin.scripts.scriptHashOutput(branch_redeem_script.getHash()) var multisigAddress = bitcoin.Address.fromOutputScript(scriptPubKey).toString() console.log("MultiSig Address: " + multisigAddress); console.log("Redeem script: " + branch_redeem_script.buffer.toString('hex'));
console.log(""); console.log("Ok. Now you FUND the account with something of MORE than 0.0001 bitcoins (that's the minimum)"); console.log("");
// Make Transaction var Transaction = bitcoin.Transaction; var TransactionBuilder = bitcoin.TransactionBuilder;
var BitcoinToSendTo = "1GzUEmh472VwWydkhY4vDQMqY3xFpZRcKs"; var addrToSendTo = Address.fromBase58Check(BitcoinToSendTo); var branchToSendTo = scripts.pubKeyHashOutput(addrToSendTo.hash);
// Just repeating what's above to reiterate and segregate the code BitcoinAddress2 = "112jFbM3Lp3qRSjezGFCv2rejT3UQ6rH5Z"; addr2 = Address.fromBase58Check(BitcoinAddress2); branch2 = scripts.pubKeyHashOutput(addr2.hash);
// Unspent amount: from https://blockchain.info/unspent?active=3PcxJeW5f6Tp4mVAXe4ggGRvDREAPCMF4o var test_output = {"unspent_outputs":[ { "tx_hash":"3be8387e161bfc927cd4d06e4f1a800806ba509f74185709ee460967fe1d57c5", "tx_hash_big_endian":"c5571dfe670946ee095718749f50ba0608801a4f6ed0d47c92fc1b167e38e83b", "tx_index":74160687, "tx_output_n": 0, "script":"a914f08e151def9e83a2d96b44b5d87c719dcd374d8a87", "value": 200000, "value_hex": "030d40", "confirmations":0 } ]};
var branch_redeem_script2 = branch_builder.script(branch_redeem_script.buffer.toString('hex')); var spend_builder = new TransactionBuilder(); spend_builder.addInput(test_output['unspent_outputs'][0]['tx_hash_big_endian'], 0); spend_builder.addOutput("1Dc8JwPsxxwHJ9zX1ERYo9q7NQA9SRLqbC", test_output['unspent_outputs'][0]['value'] - 10000);
var priv2 = ECKey.fromWIF('L3MRgBTuEtfvEpwb4CcGtDm4s79fDR8UK1AhVYcDdRL4pRpsy686'); var gp_builder = new BranchingTransactionBuilder(spend_builder);
// input 0 of the tx, second branch of 2 (index 1) gp_builder.selectInputBranch(0, 1, 2); gp_builder.signBranch(0, priv2, branch_redeem_script2, null, branchToSendTo); var tx = gp_builder.build();
console.log(tx.toHex());
Sweet. We should probably: 1) Write a test for the other branch as well 2) Try sending the tx to a 0.10 node before using blochain.info/pushtx on it to prove that the network will really take these things when it starts to upgrade.
|
|
|
@edmundedgar; using your code and your "bitcoin-branching-transaction-builder" project (and Peter Todd's public Bitcoin Address so he could sign a TRANSACTION) var bitcoin = require('bitcoinjs-lib'); var BranchingTransactionBuilder = require('./src/branching_transaction_builder'); var Script = bitcoin.Script;
var BitcoinAddress1 = "1KYestTGTEJzM5pR7AAQ7ckBE55ytLRaDk"; var BitcoinAddress2 = "1FCYd7j4CThTMzts78rh6iQJLBRGPW9fWv"; var rules = "OP_IF OP_DUP OP_HASH160 "+ BitcoinAddress1 + " OP_EQUALVERIFY OP_CHECKSIG. OP_ELSE OP_DUP OP_HASH160 " + BitcoinAddress2 + " OP_EQUALVERIFY OP_CHECKSIG. OP_ENDIF"; var NewP2SHAddress = Script.fromASM(rules);
console.log(NewP2SHAddress.buffer.toString('hex'));
I get a bitcoin address of: 6376a90088006776a900880068 Is this right? Where is the redeemScript I just added a quick test for branching versions of pay-to-public-key-hash - hopefully this will make it clearer how it's supposed to work. Basically bitcoinlib-js takes care of making the bits inside the OP_IF branching, and my thing takes care of putting them together in a branching script, so you don't need to put in your own scripting from the ASM code or anything. https://github.com/edmundedgar/bitcoin-branching-transaction-builder/blob/master/test/branching_transaction_builder.js#L81Blockchain.info took my redeeming TX (the non-standard one) - let's see if it'll confirm in a reasonable time (or at all...) https://blockchain.info/tx/7d8cf0dac56e90bfff76cee1a13464cc07f0ac36241b6703a894d28987630218Edit to add: Yup, Eligius took it. Some of the other suggestions people have made here will be variously more flexible (for more combinations of conditions) and more economical (in saving a few bytes) than mine, but you'll have to work out how to sign them since my code won't help you. YMMV, let us know how you get on...
|
|
|
Technically an address can be created from the hash of a custom script (P2SH) but I am unsure if there are the necessary op_codes in the scripting language to allow you to validate against signature of one of many pubkeyhashes.
You can do "or" cases like this with branching OP_IFs (inside P2SH). Simplest case 1/2: OP_IF OP_DUP OP_HASH160 <address1> OP_EQUALVERIFY OP_CHECKSIG. OP_ELSE OP_DUP OP_HASH160 <address2> OP_EQUALVERIFY OP_CHECKSIG. OP_ENDIF ...then sign with an OP_1 or OP_0 flag on the end to say which branch should be used. For JavaScript this may help: https://github.com/edmundedgar/bitcoin-branching-transaction-builderI haven't tried it for this specific case, but I think it would be OK. This is currently non-standard, but it should become standard as people start running bitcoin 0.10. In the meantime you should be able to broadcast it with blockchain.info, and it should get mined by Discus Fish or Eligius, which will generally get it mined in an hour or two.
|
|
|
Thank you DeathAndTaxes;
How can I make a multiSig address with just regular Bitcoin Addresses?
I'm trying to create a bitcoin address where any ONE of TWO (or THREE) bitcoin private addresses can SIGN a transaction.
You could make a special script to do this, but you'd probably need some special software to sign it. Is that an acceptable requirement? If so we can talk about the best way to script it.
|
|
|
|