Le domaine de l'invention est l'utilisation de crypto-monnaies et la génération automatique de transactions, notamment pour permettre la mutualisation des risques dans une communauté. Dans un système de crypto-monnaie tel que le système BitCoin, des transactions permettent de transférer des unités de compte entre adresses créées à partir de clés publiques cryptographiques. Chaque transaction a en entrée un input se référant à un output d'une transaction précédente (ou plusieurs inputs se référant chacun à un output d'une transaction précédente) et peut elle-même avoir un nouvel output (ou plusieurs nouveaux outputs) spécifiant un nombre d'unités de compte et une adresse de bénéficiaire. Lesdites adresses constituent les noeuds d'un réseau de transactions de crypto-monnaie (ci après le réseau) dont les transactions forment les liens. Les transactions sont validées collectivement dans le réseau et forment une structure partagée dans le réseau appelée chaîne de blocs (« blockchain » en terminologie anglo-saxonne) jouant le rôle d'un livre de comptes mais contenant en plus l'historique des transactions. En effet, quand un individu A fait un transfert d'un certain nombre d'unités de compte depuis une de ses adresses vers une des adresses d'un individu B, A doit prouver d'où elles viennent. Et ainsi, il transmet une information du type "ces unités de compte sont celles que j'ai obtenues quand C me les a envoyées il y a deux jours". Et comme tous les utilisateurs possèdent la même copie de la chaîne de blocs, tout le monde peut vérifier que C les a effectivement envoyées à A et qu'elles n'ont pas déjà été envoyées par A. Plus loin, on peut aussi vérifier comment C les a lui-même obtenues et ainsi remonter la chaîne de leurs propriétaires successifs. Autrement dit, on peut reconstruire l'histoire des transactions. Enfin, la validation collective des transactions sert à tendre vers un consensus de réseau par des techniques connues en soi, telles que les techniques « Proofof-Work » et « Proof-of-Stake » de validation des transactions annoncées (« broadcast », diffusées) dans le réseau. Chaque transaction validée est insérée dans un bloc de la chaîne de blocs, bloc organisé en arbre de Merkle de façon à ce que toute tentative de modification de la transaction violerait l'intégrité de toute la chaîne de blocs à partir du bloc la contenant, ce qui donc signifie que les transactions insérées dans la chaîne de blocs ne peuvent plus être modifiées.
Résumé de l'invention On définit ici une communauté comme un sous-ensemble du réseau. Il s'agit d'un ensemble de noeuds dans le réseau, correspondant à des individus qui se mutualisent pour mettre dans un « pot commun », le montant nécessaire à pourvoir collectivement à des paiements (transactions) de chacun, paiements ayant une probabilité d'occurrence inférieure à 1. Les paiements des membres peuvent ainsi se faire à partir dudit pot commun (ci-après dénommé pot) dans des cas définis à l'avance. La présente invention vise à permettre d'assurer une telle mutualisation, sans besoin d'un intermédiaire financier, en étant fiable et en étant extrêmement 15 souple sur les contraintes de distribution et de restitution des unités de compte accumulées dans le pot commun. On propose ainsi selon l'invention, selon un premier aspect, un système transactionnel à architecture répartie en peer-to-peer, mettant en oeuvre des transactions permettant de transférer des unités de compte entre noeuds 20 émetteurs d'unités et noeuds receveurs d'unités, chaque transaction ayant en entrée un input se référant à un output d'une transaction précédente (ou plusieurs inputs se référant chacun à un output d'une transaction précédente) et ayant elle-même au moins un nouvel output spécifiant un nombre d'unités de compte et un noeud receveur, caractérisé en ce qu'il met en oeuvre : 25 des transactions dites transactions amont qui ont un output vers un identifiant de noeud receveur, des transactions aval (transactions générées) contenant dans un input un programme (contrat) et un ensemble de paramètres (contexte d'invocation), des transactions aval ne pouvant être alimentées qu'à partir de transactions amont ayant pour identifiant de noeud receveur (Pot) dans leur output une valeur égale à celle résultant de l'application d'une fonction de hachage prédéterminée sur un ensemble d'informations contenant le programme et les paramètres, le programme et les paramètres contenus dans un input d'un transaction aval donnée définissant des contraintes implicitement émises au niveau d'une transaction amont qui l'alimente, ces contraintes étant relatives à un ou plusieurs montants de la transaction aval, et à un ou plusieurs identifiants de noeud receveurs pour ces montants, une transaction aval ne pouvant être validée que si de telles contraintes émises au niveau d'au moins une transaction amont sont satisfaites. Selon un second aspect, on propose un procédé de gestion d'unités de compte mises en commun dans un système transactionnel à architecture répartie en peer-to-peer, mettant en oeuvre des transactions permettant de transférer des unités de compte entre noeuds émetteurs d'unités et noeuds receveurs d'unités, chaque transaction ayant en entrée un input se référant à un output d'une transaction précédente (ou plusieurs inputs se référant chacun à un output d'une transaction précédente) et ayant elle-même au moins un nouvel output spécifiant un nombre d'unités de compte et un noeud receveur, le procédé comprenant les étapes suivantes : prévoir des transactions dites transactions amont ayant un output vers un identifiant de noeud receveur, prévoir des transactions aval (transactions générées) contenant dans un 25 input un programme (contrat) et un ensemble de paramètres (contexte d'invocation), pour une transaction aval donnée, appliquer une fonction de hachage prédéterminée sur un ensemble d'informations contenant le programme et les paramètres contenus dans l'input de ladite transaction aval, et considérer la ou les transactions amont dont l'identifiant de noeud receveur (Pot) est égal au code de hachage obtenu par la fonction de hachage, seules de telles transactions amont pouvant être validées comme alimentant ladite transaction aval, pour une transaction aval donnée, exécuter le programme en utilisant lesdits paramètres pour retrouver la contrainte implicitement émise au niveau d'une transaction amont qui l'alimente, cette contrainte étant relative à un ou plusieurs montants de la transaction aval, et à un ou plusieurs identifiants de noeud receveurs pour ces montants, et valider une transaction aval seulement si la contrainte émise au niveau 10 d'au moins une transaction amont est satisfaite. Brève description des dessins La figure 1 présente schématiquement le procédé de l'invention sur un exemple. La figure 2 est un diagramme de séquence décrivant les interactions entre les différentes entités participant au procédé. 15 La figure 3 introduit le procédé de l'invention sur un exemple de deux fournisseurs qui se mutualisent. La figure 4 présente les contributions apportées par un troisième fournisseur dans l'exemple de la figure 3. La figure 5 montre la généralisation du procédé présenté dans la figure 3 afin de 20 pouvoir le mettre en oeuvre sous la forme d'un programme contrat qui est présenté dans 1' Annexe 1. Description détaillée Dans le système Bitcoin, un output peut être conditionnel au sens où il ne peut être consommé qu'à certaines conditions qui y sont spécifiées. Notamment, 25 Bitcoin permet de spécifier (dans un « script ») une condition de « 2 signatures sur 3 » (CHECKMULTISIG), par exemple une condition de deux signatures à fournir parmi les signatures (i) d'un fournisseur, (ii) d'un client et (iii) d'un arbitre, ce dernier devant donner sa signature en cas de dispute entre le fournisseur et le client. Récemment, il a été introduit, dans Bitcoin, l'option de pouvoir spécifier la condition d'un output en plaçant dans l'output le hash-code (dit « Pay to Script Hash ») de cette condition, qui elle doit se trouver en clair dans l'input de la transaction qui consomme cet output (condition qui doit être satisfaite pour que ladite transaction soit valide). Ce procédé est décrit dans le BIT 16 Bitcoin Improvement Proposai, https://github.cornibitcoireelblobimasteribip0016.mediawiki (plus tard il le sera aussi dans le wiki httpsVien.bitcoinitiwikieransactions#Pay-to-Scriptilash), dont le contenu est ici considéré comme faisant partie de la présente description. Actuellement, les conditions qui peuvent être exprimées dans Bitcoin sont des conditions de signature, la ou les signatures en question devant être fournies dans ledit input. La partie gauche de la Figure 1 en présente un exemple : Une transaction « Txl » offre 1000 unités de compte à un noeud receveur identifié par un code de hachage dénommé ici « C1 » (dans le BIP-16 ii s'uJit du « [20-byte-hash-value]» du « OP_l-IASH1.6O [20-byte-hash-value] OP EQUAL, >), ces 1000 unités ne pouvant être consommées que par un input qui comprenne un script (il s'agit du « lserialized script} » nentionné dans fe 13 [P-16) dont le code de hachage (obtenu en appliquant une fonction de hachage prédéterminée sur son contenu) est ce Cl et qui comprenne une ou des signatures qui satisfont la condition spécifiée dans ce script. Quant à la partie droite de la Figure 1, elle présente exactement le même paiement conditionnel que dans la partie gauche mais en introduisant une indirection selon le procédé de l'invention : Les 1000 unités sont, dans une première transaction (dite transaction amont), « Tx1.1 », payés à un noeud receveur « P1 » (que l'on appelle Pot), à partir duquel, dans une deuxième transaction (dite transaction générée ou transaction aval), « Tx2.1 », le paiement conditionnel de 1000 unités doit être conforme à une contrainte (représentée par « 1000@C1 » pour dire que la transaction générée doit forcément consister à payer 1000 unités avec la condition représentée par Cl) imposée par la première transaction (c'est pour cela que dans la figure, la contrainte est présentée en italique sur l'output de la transaction amont) via le code hachage représentant le Pot dans l'output de Tx1.1, code qui doit être retrouvé lorsqu'on applique la fonction de hachage prédéterminée au contenu de l'input de Tx2.1 qui permette de retrouver cette contrainte. Autrement dit, pour que Tx2.1 soit valide, l'application de la fonction de hachage prédéterminée au contenu de l'input de Tx2.1 doit donner Pl, et Tx2.1 doit être 10 conforme à la contrainte (ici la contrainte 1000@C1) produite par cet input. (On décrit plus loin comment cette contrainte est produite.) A noter que, comme on le voit dans la suite, une transaction générée peut avoir plusieurs inputs et pour être valide il suffit qu'elle soit conforme à la contrainte issue d'au moins un de ces inputs. 15 L'état de l'art ne permet pas de valider les outputs d'une transaction aval par rapport à des contraintes émises au niveau d'une transaction amont. On va dans la suite prendre l'exemple de fournisseurs (Fi) qui dans des transactions (Txti) mettent en séquestre des unités de compte qui ne pourront être débloquées que si (selon la condition Ci) le client (correspondant à ce Ci) 20 est d'accord (et donc que le fournisseur et le client signent tous les deux, quel que soit le bénéficiaire décidé par eux) ou si l'arbitre signe soit avec le fournisseur soit avec le client (condition de deux signatures sur trois précitée). Les séquestres (avec ces conditions de signatures) ont pour but d'assurer aux clients respectifs que s'ils ne sont pas livrés de manière satisfaisante, les unités 25 de compte séquestrées leurs reviendront. Dans une mise en oeuvre avec « mutualisation de risques », les fournisseurs s'organisent en « communauté » et utilisent le procédé de l'invention pour faire des mises (d'unités de compte) en séquestre dans un « Pot commun » (désigné par le code de hachage « Pot » mentionné plus haut), les engagements des 30 fournisseurs envers les clients se faisant ainsi via ce pot commun plutôt que directement par chacun. Ainsi, la probabilité de devoir payer un client étant inférieur à 1, plus le pot se remplit plus les mises des fournisseurs respectifs deviennent relativement plus faibles. On a vu que « Pot » est le code de hachage du contenu de l'input d'une 5 transaction générée, input permettant de produire des contraintes telle que 1000@C1 qui seront vérifiées sur les outputs de la transaction générée elle-même. Ces contraintes sont produites par l'exécution d'un programme dénommé contrat (ou « contrat de communauté », qui lie les membres de la communauté en question en ce qui concerne les modalités des mises en 10 séquestre) sur des paramètres appelés contexte d'invocation (ou contexte). Tant le contrat -ou du moins une référence sur un tel contrat, permettant de le retrouver lors des validations- que le contexte d'invocation -ou une référence à celui-ci- font partie de l'input de la transaction générée. Les différents fournisseurs se contraignent mutuellement pour leurs mises en 15 séquestre du fait qu'ils partagent un même contrat. Pour toutes les mises en séquestre par les membres d'une communauté donnée, les transactions Tx2i sont générées en l'application du même contrat. A noter que des « commentaires » (non exécutés) peuvent être insérés dans le contenu du contrat pour permettre à des communautés distinctes d'utiliser un même 20 contrat mais en produisant des codes de hachage « Pot » différents qui seront respectivement mis dans l'output de la transaction amont. En résumé, les transactions selon ce procédé sont caractérisées en ce qu'elles contiennent les éléments suivants : - Dans l'output de la transaction amont : 25 i. Valeur : nombre d'unités de compte ii. Hash(Contrat + Contexte d'invocation) : code de hachage « Pot » (comme le « [20-byte-hash-value] » du « OP JIASH160 [20-byte-hash-value] OP_EQUAL » du F31P 16) résultant de l'application de la fonction de hachage prédéterminée sur le 30 contenu de l'input de la transaction générée - Dans l'input de la transaction générée : L Contrat ii. Contexte d'invocation Et la validation consiste à vérifier le code de hachage donné dans l'output à l'amont et à exécuter ledit Contrat sur ledit Contexte d'invocation pour : 1. obtenir les contraintes (contraignant les outputs de la transaction générée) et ensuite 2. vérifier que pour un input de la transaction générée la contrainte obtenue est satisfaite (ceci sera illustré dans les exemples présentés plus loin).1 Le contrat et le contexte d'invocation peuvent être des références. La vérification se satisfait de la conformité d'un seul input (c'est-à-dire qu'il suffit de satisfaire les contraintes émises par un seul output connecté) car une transaction générée ne peut pas satisfaire des contraintes émises par une transaction amont antérieure à sa propre transaction amont or il peut avoir un input qui en bénéficie (comme on va le voir dans l'exemple qui suit, présenté dans la figure 3). On va maintenant décrire comment est créée une communauté et comment s'effectue la mutualisation de risques. Le principe est que le premier fournisseur joue un rôle de coordinateur (Root), sachant qu'il est remplacé par un suivant lorsqu'il quitte la communauté, et qu'il informe les autres fournisseurs du contexte, selon le protocole présenté à la figure 2. Le contexte ainsi communiqué aux membres de la communauté comprend l'ensemble des outputs (de mises en séquestre de fournisseurs) disponibles dans le pot où 1 Ainsi, au lieu de classiquement signer avec une clé privée correspondant à une clé publique (ou à une adresse obtenue à partir d'une clé publique), on donne dans la transaction générée le contrat et le contexte d'invocation qui correspondent exactement au contrat et au contexte d'activation voulus au moment de la création de la transaction amont et qui ont permis d'obtenir le code de hachage donné dans son output. Alors, dans la mesure où la transaction générée effectue les paiements voulus par le contrat dans le contexte d'invocation du contrat, elle est valide. pourront puiser chaque nouveau fournisseur pour payer leurs clients le cas échéant, le restant des unités de compte des output étant remis au pot pour les prochains. Les nouveaux fournisseurs complètent les paiements des autres fournisseurs dans les cas où ils ne couvrent pas entièrement leurs engagements envers leurs propres clients, ceci est décrit plus loin et illustré à la figure 4. La figure 2 est un diagramme de séquence présentant les interactions entre les différents acteurs impliqués. F., Fn_i et Root sont des fournisseurs, C. et Ci sont des clients, 'Blockchain' représente le réseau (une flèche vers Blockchain indique le fait d'annoncer une ou des transactions dans le réseau en vue de la ou les faire inclure). Les numéros indiqués correspondent aux étapes suivantes : 1. Le fournisseur F. est introduit par le fournisseur F'_i qui lui donne la connexion de Root (le créateur de la communauté, ou chaque fois le fournisseur suivant lorsqu'un Root courant quitte la communauté) 2. F. demande confirmation à Root, en fournissant l'identifiant de Fn-1 3. Dans le cas d'une confirmation, Root fournit le contexte (l'état courant de la communauté) : l'ensemble des outputs disponibles + l'ensemble des valeurs (nombre d'unités de compte) attendus par les Clients respectifs 4. Fn hache le contrat et le contexte, et génère les contraintes et les transactions correspondantes 5. F. annonce son paiement dans le réseau 6. Fn envoie à Root une mise-à-jour du contexte 7. Fn informe son client C. des transactions qui sont à sa disposition 8. Fn informe les autres clients des transactions complémentaires dont ils pourront bénéficier. On peut bien entendu envisager un système pour assister les fournisseurs (ou autres acteurs qui se mutualisent) à générer des transactions, ainsi que pour assister les clients (ou autres bénéficiaires potentiels de ces transactions) à créer des transactions pour se faire payer et annoncer les bonnes transactions générées dans le réseau. Le contrat peut être prévu pour tenir compte de préférences (fournies dans le contexte d'invocation) quant aux nombre de transactions générées souhaitées (en ignorant le cas échéant les mises en séquestre, dans le pot commun, de certains des fournisseurs). La partie droite de la figure 1 présentait la mise au pot de 1000 unités d'un premier fournisseur (suite à la création d'une nouvelle communauté et de son contrat). La figure 3 présente en plus les transactions ajoutées pour un deuxième fournisseur. On voit dans cette figure quatre lignes de transactions, selon l'ordre de consommation des outputs des premières transactions Txl.i. Ainsi, en cas de défaut de livraison par deux fournisseurs Fl et F2 à deux clients respectifs Cl et C2, la première ligne de transactions présente le cas d'un premier paiement au client Cl par le fournisseur Fl en cas de défaut de livraison de Fl à Cl, la deuxième ligne concerne le cas du paiement à Cl par Fl après que C2 a été payé en cas de défauts de livraison successifs, la troisième ligne présente le cas d'un premier paiement à C2 en cas de défaut de livraison de F2 à C2, et la quatrième ligne le cas du paiement de C2 par F2 après que le paiement de Cl a déjà été effectué. La restitution des sommes mises en séquestre aux fournisseurs dans le cas où les livraisons ont été correctement assurées s'effectue selon le même processus, les bénéficiaires des transactions pouvant dans ce cas être Fl ou F2 à la place de 20 Cl ou C2. L'ajout d'une nouvelle mise en séquestre dans le pot permet de complémenter les transactions qui ne payaient pas l'entièreté des montants attendus par les clients. Par exemple, en ce qui concerne la séquence « C2 Cl », Tx2.2.2 ne paie que 950 unités alors que le client s'attend à en recevoir 1000. La figure 4 25 présente des transactions supplémentaires pour les séquences « C2 Cl » et « Cl C2 » où des inputs sont connectés à des mises en séquestre d'un troisième fournisseur (non présentées dans la figure). La figure 5 présente une manière de généraliser le procédé et faciliter ainsi la mise en oeuvre du contrat dont un exemple est présenté (en formalisme XML) 30 dans l'Annexe 1. 301 8 3 7 7 11 Ainsi, pour le contexte suivant où il y a les 3 fournisseurs F1, F2, F3, leurs clients respectifs C1, C2, C3, ces fournisseurs mettant respectivement en séquestre 1000, 950 et 900 unités de compte : List<Output> availableOutputs = new LinkedList<Output>(); 5 availableOutputs.add(new Output(1000,"F1")); availableOutputs.add(new Output(950,"F2")); availableOutputs.add(new Output(900,"F3")); List<ClientRequirement> currentRequirements = new LinkedList<ClientRequirement>(); 10 currentRequirements.add(new ClientRequirement(1000, "Cl")); currentRequirements.add(new ClientRequirement(1000, "C2")); currentRequirements.add(new ClientRequirement(1000, "C3")); ce programme fournit la liste de contraintes suivantes (auxquelles les transactions générées doivent se conformer) : 15 1000.0@C1+1850.0@((1000.0@C2+850.0@(850.0@C3)) II (1000.0@C3+ 850.0@(850.0@C2))) 1000.0@C2+1850.0@((1000.0@C1+850.0@(850.0@C3)) I I (1000.0@C3+ 850.0@(850.0@C1))) 1000.0@C3+1850.0@((1000.0@C1+850.0@(850.0@C2)) I I (1000.0@C2+ 850.0@(850.0@C1))) Une deuxième option de mise en oeuvre consiste à envisager une extension du Pay-to-PubkeyHash (https://en.bitcoinitjwikeransactions#Pay-to- PubkeyHash) de Bitcoin plutôt que le Pay-to-PubkeyHash considéré plus haut. On peut ainsi envisager le schéma suivant : - Dans l'output de la transaction amont : i. Valeur ii. Script 1. Contexte d'invocation (ou référence) 2. Adresse = hash du Contrat (qui constituera le Pot) - Dans l'input de la transaction générée : i. Contrat ou Référence au contrat (ainsi les mineurs pourront l'exécuter et retrouver les Contraintes) - Vérification de la transaction générée : i. Adresse = hash du Contrat (donné dans l'input de la transaction générée ) ii. Obtenir les Contraintes (en exécutant le Contrat) et vérifier la conformité de la transaction générée. Ou encore le suivant : - Dans l'output de la transaction amont : i. Valeur ii. Script 1. Contexte d'invocation (ou référence) 2. Contrat ou Référence au contrat (ainsi les mineurs pourront l'exécuter et retrouver les Contraintes) 3. Adresse = hash du Contrat (qui constituera le Pot) - Vérification de la transaction générée : i. Adresse = hash du Contrat (donné dans l'input de la transaction générée ) ii. Obtenir les Contraintes (en exécutant le Contrat) et vérifier la conformité de la transaction générée. Ces procédés peuvent être combinés entre eux. Quelle que soit l'approche, le 25 procédé de l'invention prévoit une mise en séquestre dans un pot commun afin de permettre la mutualisation des différents payeurs pour faire face à leurs engagements de séquestre tout en bloquant moins d'argent à l'avance. Dans ce texte on a décrit l'invention en donnant l'exemple d'une mise en séquestre par un fournisseur pour rassurer un client, mais on peut bien sûr 30 aussi appliquer exactement le même procédé pour la mise en séquestre d'un client pour rassurer un fournisseur, l'avantage de la mutualisation (des risques) entre fournisseurs se retrouvant dans le cas d'une mutualisation entre clients. Ces termes peuvent ainsi être librement échangés. Le procédé de l'invention consistant à étendre un système tel que Bitcoin pour permettre d'utiliser un « pot commun » de mutualisation peut s'appliquer à tous les cas de mutualisation de risques. On peut par exemple mutualiser des risques de maladie ou d'accident et mettre en séquestre des unités de compte pour couvrir des dépenses de traitement médical...
ANNEXE - Input Script & Contract <Script> <Context> <AvailableOutputs> <Output address="F1" amount="1000" /> <Output address="F2" amount="950" /> <Output address="F3" amount="900" /> </AvailableOutputs> <ClientRequirements> <ClientRequirement client="C1" amount="1000" /> <ClientRequirement client="C2" amount="1000" /> <ClientRequirement client="C3" amount="1000" /> </ClientRequirements> </ Context> <Contract> class Output { double amount; String address; String toString(){ return address+":"+amount; } Output(double amount, String address) { setAmount(amount); setAddress(address); } } 14 class ClientRequirement { double amount; String client; String toString0{ return client+":"+amount; } ClientRequirement( double amount, String client) { setAmount(amount); setClient(client); } } class Constraint double amount; String cldest; List<Constraint> dest = new LinkedList<Constraint>(); List<Constraint> otherOutputs = new LinkedList<Constraint>(); String toString() { String result = "" + amount + "@'; if (cldest != null) { result += cldest; } else { result += "("; if (dest.size() > 1) { for (int i = 0; i < dest.size(); i++) { Constraint c = dest.get(i); if (i < dest.size() - 1) { result += "(" + c + ") I I"; } else { result += "(" + c + ")"; } } } else if (dest.size() > 0) { result += dest.get(0); result += "r; } for (Constraint c : otherOutputs) { result += "+" + c; } return result; } Constraint(double amount, String cldest) { setAmount(amount); setCldest(cldest); } Constraint(double amount, List<Constraint> dest) setAmount(amount); setDest(dest); } void addToDest(Constraint c) dest.add(c); void addToOtherOutput(Constraint c) otherOutputs.add(c); } } double sum(List<Output> outputs) double result = 0; for (Output o : outputs) result += o.getAmount(); } return result; } List<Constraint> generateConstraints(List<Output> availableOutputs, List<ClientRequirement> currentRequirements) List<Constraint> results = new LinkedList<Constraint>(); double total = sum(availableOutputs); for (ClientRequirement clr : currentRequirements) Constraint c = null; if (total > clr.getAmount()) { c = new Constraint(c1r.getAmount0, clr.getClient()); if (total - clr.getAmount() > 0) { List<Output> newL0 = new LinkedList<Output>(); newLO.add(new Output(total - clr.getAmount(), "POT")); List<ClientRequirement> remainingRequirements = new LinkedList<ClientRequirement>(); remainingRequirements.addAll(currentRequirements); remainingRequirements.remove(c1r); List<Constraint> dest = generateConstraints(newL0, remainingRequirements); Constraint otherC = new Constraint(total - clr.getAmount(), dest); c.addToOtherOutput(otherC); } } else { c = new Constraint(total, clr.getClient()); results.add(c); } return results; } </Contract> </Script>